int count = 1; Set s1 = new HashSet(); Set s2 = new HashSet(); list l = new ArrayList();while(s1.size()<3) { s1.add(Math.random()*100000); }for (int i = 0;i<100000;i++) { if(!s1.contains(i)) s2.add(i); }如果jdk1.5以上版本,可以直接foreach遍历 for(int j : s2) { if(s1.contains(j)) l.add(j); } 没有验证,临时写的。多多指教。呵呵
Random ran=new Random(); int ranA=ran.nextInt(10000); int ranB=ran.nextInt(10000); String A[]=new String[10000]; for(int i=0;i<A.length;i++){ if(i!=ranA && i!=ranB){ A[i]=Integer.toString(i); }else{ System.out.println("取出的数字是"+i); } }
是这个意思吗?我不清楚不能定义数组是什么意思,诶。
这个方法是可以的 只是你不用计算出整个1-100000的积 我们只要知道x*y的积就好了 double t = 1; for(int i = 0; i < 99998; i++) { t *= i/A[i] } 所以x*y = 100000 * t * 99999
晕,看错题了。给出数组A的话:Set s = new HashSet(); list l = new ArrayList();for (int i = 0;i <100000;i++) { s.add(i); }for(int j : s) { for(int k=0;k<A.lenght();k++) { if(j!=A[k]) l.add(j); } }
double t = 1; //积 double n = 0; //和 for(int i = 0; i < 99998; i++) { t *= i/A[i]; n += A[i]; } t *= (100000*99999); n = 50000*100001 - n; 解方程组 x + y = n x * y = t 遍历数组一次 变量个数也满足
在11楼基础上更正下 double t = 1; // 积 double n = 0; // 和 for (int i = 0; i < A.length; i++) { t = t * (i + 1) / A[i]; n += A[i]; } t *= (100000 * 99999); n = 50000 * 100001 - n; // 解方程组 // x + y = n // x * y = t // 遍历数组一次 // 变量个数也满足
int index = 8; for(int i = 0; i<a.length; i++){ while( a[i] != i+1){ if(a[i]== 0){ index = i; System.out.print("!"+(index+1)); break; }else{ int temp = a[a[i]-1]; a[a[i]-1] = a[i]; a[i] = temp; } } } // for(int i:a){ // System.out.print(":"+i); // } }输出: !1!8我写的,还有点小瑕疵,再让我想想~
Arrays.sort(a); for (int i = 1; i < 100001; i++) { if (a[i - 1] != i) { System.out.println("被拿出的数为:" + i); } }
/** 面试厦门欧乐时的一道编程题,拿出来大家共同学习一下:从1到100000中随意取出两个数,然后将其余99998个数打乱放入数组A中,现在要求遍历一次数组A,就要找到取出的那两个数。要求:最多只能定义5个变量,不能定义数组。大家有兴趣的试试。 我假设这两个数为99999,100000 */ public class SearchTwo{ public static void main(String args[]){ long[] A = new long[99998]; for(int i=0;i<99998;i++){ A[i]=i+1; if(i>99990){ System.out.println("i="+i); System.out.println("A[i]="+A[i]); } } long t = 1; // 积 long n = 0; // 和 for (int i = 0; i < A.length; i++) { t = t * (i + 1) / A[i]; n += A[i]; } System.out.println("积:"+t); System.out.println("和:"+n); t = t*100000*99999; //long k=50000; //long m=100001; //System.out.println("积--------------:"+k*m); n = (long)50000*100001-n;
System.out.println("积:"+t); System.out.println("和:"+n); long x = (long)(Math.sqrt(n*n-4*t)-n)/(-2); System.out.println("x="+x); System.out.println("y="+(n-x)); // 解方程组 // x + y = n // x * y = t // 遍历数组一次 // 变量个数也满足 } }
/** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub check(); }} 搞定啦~大家帮忙看下啊~高手指点下啊~
随你怎么打乱,我用 Arrays.sort 不就行啦!
其实一直在思考 arraylist是不是数组。
在24楼的基础上写了下 还可以改很多哈 只是实现了! public static void test(){ int[] a=new int[100000]; Random random=new Random(); int v=random.nextInt(100000); int s=random.nextInt(100000); System.out.println("随机数是:"+v+"和"+s); for (int i = 0; i < a.length; i++) { if (i==v||i==s) { continue; } a[i]=i; } for (int i = 1; i < 100000; i++) { if (a[i]!=i) { System.out.println("拿出的是"+i); } } }
public static int[] test(int[] a) { int[] missed = new int[2]; Set set = new HashSet(); for (int index = 0; index < a.length; index++) set.add(a[index]); int index = 10000, i = 0; Iterator iter = set.iterator(); while (iter.hasNext()) { if (index!=Integer.parseInt(iter.next().toString())) { missed[i] = index; i++; index--; } index--; } return missed; }试试这个,原理是采用hashset的自动排序功能,得到的set里面所有的数字是从大到小排列的,然后用查看究竟少了那个数字返回到数组missed中, 大家不用构造数组A,因为A是已知的。
引用 24 楼 zhaitao81 的回复: Arrays.sort(a); for (int i = 1; i < 100001; i++) { if (a[i - 1] != i) { System.out.println("被拿出的数为:" + i); } }
unsigned long A=expectDSum-arrayDSum; unsigned long B=expectSum-arraySum; unsigned long C=(2*A-B*B); std::cout<<"x+y="<<B<<'\t' <<"x*x+y*y:"<<A<<'\n' <<"2*A-B*B:"<<C<<'\n'; unsigned long x_y=sqrt(C); std::cout<<"x-y:"<<x_y<<'\n'; std::cout<<"x:"<<(x_y+B)/2<<'\n'; std::cout<<"y:"<<(B-x_y)/2<<'\n'; return 0; } int main() { int array[MAX]; for(int i=0;i<MAX;++i) array[i]=i+1;
show(array,MAX);
srand(time(NULL)); for(int i=0;i<MAX;++i) { int start=rand()%MAX; int temp=array[i]; array[i]=array[start]; array[start]=temp; } show(array,MAX);
哦,如果是这样,那可以先乘大数 double t = 1*2; // 积 double n = 0; // 和 for (int i = 0; i < A.length; i++) { t = t * (100000-i) / A[i]; n += A[i]; } n = 50000 * 100001 - n; // 解方程组 // x + y = n // x * y = t
1-100000的和-数组A中所有数的和=未知数X+Y的和
1-100000的积/数组A中所有数的积=未知数X*Y的积
然后很容易能解出来
但回头一想,1-100000的积应该是一个很大的数,这方法...
咳
就是给你一个数组A里头有被打乱的99998个数
让你找出数组A中少了1-100000中的哪两个数
Set s1 = new HashSet();
Set s2 = new HashSet();
list l = new ArrayList();while(s1.size()<3)
{
s1.add(Math.random()*100000);
}for (int i = 0;i<100000;i++)
{
if(!s1.contains(i))
s2.add(i);
}如果jdk1.5以上版本,可以直接foreach遍历
for(int j : s2)
{
if(s1.contains(j))
l.add(j);
}
没有验证,临时写的。多多指教。呵呵
Random ran=new Random();
int ranA=ran.nextInt(10000);
int ranB=ran.nextInt(10000);
String A[]=new String[10000];
for(int i=0;i<A.length;i++){
if(i!=ranA && i!=ranB){
A[i]=Integer.toString(i);
}else{
System.out.println("取出的数字是"+i);
}
}
是这个意思吗?我不清楚不能定义数组是什么意思,诶。
只是你不用计算出整个1-100000的积
我们只要知道x*y的积就好了
double t = 1;
for(int i = 0; i < 99998; i++)
{
t *= i/A[i]
}
所以x*y = 100000 * t * 99999
list l = new ArrayList();for (int i = 0;i <100000;i++)
{
s.add(i);
}for(int j : s)
{
for(int k=0;k<A.lenght();k++)
{
if(j!=A[k])
l.add(j);
}
}
double n = 0; //和
for(int i = 0; i < 99998; i++)
{
t *= i/A[i];
n += A[i];
}
t *= (100000*99999);
n = 50000*100001 - n;
解方程组
x + y = n
x * y = t
遍历数组一次
变量个数也满足
double n = 0; // 和
for (int i = 0; i < A.length; i++) {
t = t * (i + 1) / A[i];
n += A[i];
}
t *= (100000 * 99999);
n = 50000 * 100001 - n; // 解方程组
// x + y = n
// x * y = t
// 遍历数组一次
// 变量个数也满足
而这种做法的原理是?
i/A[i]
只会弄出0来
1=00001
2=00010
3=00100
4=01000
5=10000
求二进制和是11111
然后假如取了1和3
那就是
2=00010
4=01000
5=10000
求二进制和是11010可以知道少了00100和00001也就是上面的1,3
public static void check(){
int[] a = new int[10];
a[0] = 5;
a[1] = 2;
a[2] = 7;
a[3] = 4;
a[4] = 3;
a[5] = 6;
a[6] = 10;
a[7] = 9;
a[8] = 0;
a[9] = 0;
int index = 8;
for(int i = 0; i<a.length; i++){
while( a[i] != i+1){
if(a[i]== 0){
index = i;
System.out.print("!"+(index+1));
break;
}else{
int temp = a[a[i]-1];
a[a[i]-1] = a[i];
a[i] = temp;
}
}
}
// for(int i:a){
// System.out.print(":"+i);
// }
}输出:
!1!8我写的,还有点小瑕疵,再让我想想~
for (int i = 1; i < 100001; i++) {
if (a[i - 1] != i) {
System.out.println("被拿出的数为:" + i);
} }
面试厦门欧乐时的一道编程题,拿出来大家共同学习一下:从1到100000中随意取出两个数,然后将其余99998个数打乱放入数组A中,现在要求遍历一次数组A,就要找到取出的那两个数。要求:最多只能定义5个变量,不能定义数组。大家有兴趣的试试。
我假设这两个数为99999,100000
*/
public class SearchTwo{
public static void main(String args[]){
long[] A = new long[99998];
for(int i=0;i<99998;i++){
A[i]=i+1;
if(i>99990){
System.out.println("i="+i);
System.out.println("A[i]="+A[i]);
}
}
long t = 1; // 积
long n = 0; // 和
for (int i = 0; i < A.length; i++) {
t = t * (i + 1) / A[i];
n += A[i];
}
System.out.println("积:"+t);
System.out.println("和:"+n);
t = t*100000*99999;
//long k=50000;
//long m=100001;
//System.out.println("积--------------:"+k*m);
n = (long)50000*100001-n;
System.out.println("积:"+t);
System.out.println("和:"+n);
long x = (long)(Math.sqrt(n*n-4*t)-n)/(-2);
System.out.println("x="+x);
System.out.println("y="+(n-x));
// 解方程组
// x + y = n
// x * y = t
// 遍历数组一次
// 变量个数也满足
}
}
给那个数组a能不能存在hashset中 如果能的话 直接循环100000 次输出不包含的 随便提议,有可能不正确,学习中
package com.trust.catchnum;public class CatchNum {
public static void check(){
//数组A[],数组A[]的特点,有length-2项顺序混乱,但是最后两个必须有两个数组单元存放-1,表示缺少的数
int[] a = new int[10];
a[0] = 6;
a[1] = 7;
a[2] = 8;
a[3] = -1;
a[4] = -1;
a[5] = 3;
a[6] = 1;
a[7] = 4;
a[8] = 9;
a[9] = 2;
//两个数
int num1 = -1;
int num2 = -1;
//计数器,记录-1值交换的次数
int count = 0;
//数组有个特点,就是排完序的数组,数组单元中的值减一为数组单元的索引,只要排序,
//然后记录下最后数组单元值为-1的数组单元索引,再加一就是缺少的数的值
for(int i = 0; i<a.length; i++){//开始遍历数组
while( a[i] != i+1){//如果索引值i加一不等于数组单元中的值
if(a[i]== -1){//当数组单元中的值为-1时进入计算
count++;//计数器加一
// System.out.println("!" + i);
//最后两次交换所得到的索引值加一为所要求的两个数
if(count%2 == 1){//奇数次交换,将索引值+1存入num1,最后一次存放的为两个数中之一的一个数
num1 = i + 1;
}
if(count%2 == 0){//偶数次交换,将索引值+1存入num1,最后一次存放的为两个数中之一的一个数
num2 = i + 1;
}
break;//跳出循环,进入下一个数组单元
}else{
//数组单元的交换,将数组单元中的值放入数组索引为其值减一的数组单元
int temp = a[a[i]-1];
a[a[i]-1] = a[i];
a[i] = temp;
}
}
}
//输出这两个数
System.out.println("first num: " + num1);
System.out.println("second num:" + num2);
//输出排序后数组
for(int i:a){
System.out.print(":"+i);
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
check(); }}
搞定啦~大家帮忙看下啊~高手指点下啊~
在24楼的基础上写了下 还可以改很多哈 只是实现了!
public static void test(){
int[] a=new int[100000];
Random random=new Random();
int v=random.nextInt(100000);
int s=random.nextInt(100000);
System.out.println("随机数是:"+v+"和"+s);
for (int i = 0; i < a.length; i++) {
if (i==v||i==s) {
continue;
}
a[i]=i;
}
for (int i = 1; i < 100000; i++) {
if (a[i]!=i) {
System.out.println("拿出的是"+i);
}
}
}
int[] missed = new int[2];
Set set = new HashSet(); for (int index = 0; index < a.length; index++)
set.add(a[index]); int index = 10000, i = 0; Iterator iter = set.iterator(); while (iter.hasNext()) { if (index!=Integer.parseInt(iter.next().toString())) {
missed[i] = index;
i++;
index--;
}
index--;
}
return missed;
}试试这个,原理是采用hashset的自动排序功能,得到的set里面所有的数字是从大到小排列的,然后用查看究竟少了那个数字返回到数组missed中, 大家不用构造数组A,因为A是已知的。
Arrays.sort(a);
for (int i = 1; i < 100001; i++) {
if (a[i - 1] != i) {
System.out.println("被拿出的数为:" + i);
} }
想法不错!!!
----------------------------------------------------------------------------------------------
楼上的想法是不可行的,在遇到第一个被拿出的数后,它后面的排序都是不同的,如假设两个数是100和105,在第一个a[100-1]=101时,可以知道拿出的是100,但执行下去,a[101-1]也是不等于101的,实际经过排序已经是102了,这样也会被输出,但101被拿出的结果是错误的,接下来的数据会全部被输出,所以这个算法是行不通的~~
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#define MAX 100000
void show(int *array,int len)
{
std::cout<<array[len-2]<<'\t'<<array[len-1]<<'\n';
return;
for(int i=0;i<len;++i)
{
if(i%10==0)
std::cout<<std::endl;
std::cout<<array[i]<<'\t';
}
std::cout<<'\n';
}
int run(int *array,int len)
{
unsigned long expectSum=(1+len+2)*(len+2)/2;
unsigned long expectDSum=(len+1)*(len+1)+(len+2)*(len+2);
unsigned long arraySum=0;
unsigned long arrayDSum=0;
for(int i=0;i<len;++i)
{
expectDSum+=(i+1)*(i+1);
arraySum+=array[i];
arrayDSum+=array[i]*array[i];
}
std::cout<<"expectSum:"<<expectSum<<'\t'
<<"expectDSum:"<<expectDSum<<'\t'
<<"arraySum:"<<arraySum<<'\t'
<<"arrayDSum:"<<arrayDSum<<'\n';
unsigned long A=expectDSum-arrayDSum;
unsigned long B=expectSum-arraySum;
unsigned long C=(2*A-B*B);
std::cout<<"x+y="<<B<<'\t'
<<"x*x+y*y:"<<A<<'\n'
<<"2*A-B*B:"<<C<<'\n';
unsigned long x_y=sqrt(C);
std::cout<<"x-y:"<<x_y<<'\n';
std::cout<<"x:"<<(x_y+B)/2<<'\n';
std::cout<<"y:"<<(B-x_y)/2<<'\n';
return 0;
}
int main()
{
int array[MAX];
for(int i=0;i<MAX;++i)
array[i]=i+1;
show(array,MAX);
srand(time(NULL));
for(int i=0;i<MAX;++i)
{
int start=rand()%MAX;
int temp=array[i];
array[i]=array[start];
array[start]=temp;
}
show(array,MAX);
run(array,MAX-2);
return 0;
}
然后减去数组里的99998个数字的和,就是x,y的和
1到100000的积是固定的
然后除去数组里的99998个数字的积,就是x,y的积然后解方程 不就出来了
只能遍历一次数组~你这样遍历了n次了~
哦,如果是这样,那可以先乘大数
double t = 1*2; // 积
double n = 0; // 和
for (int i = 0; i < A.length; i++) {
t = t * (100000-i) / A[i];
n += A[i];
}
n = 50000 * 100001 - n; // 解方程组
// x + y = n
// x * y = t
毕竟 看不到for 和whlie,,哈
假设数组a[10000]
打乱之后,
int temp = 0;
int time = 0;
for(int i =0; i<10000; i++) {
while(i != a[i]-1) { //当前位置数组的值与当前的位置不匹配 如:a[0]=1;为匹配。
time = time +1;
temp = a[a[i]-1];
a[a[i]-1] = a[i]; //把它放在正确的位置。例如:a[0]=7; 则a[6]=7;
a[i] = temp; //继续寻找 a[0]=a[6];直到找到a[0]=1结束。
if(time>9999) { //没有找到正确的位置。
System.out.println(i+1); //输出
}
}
time = 0;
}
不知道,对不对?
找第一个位置的时候最费时了,最坏的情况可能找9次,但是以后的找位置就轻松了,因为他们都是“匹配的”。
效率的话应该很高。
大家给看看!呵呵