抽屉原理2--关于抽屉的循环问题

来源:互联网 发布:飞升仙兵升级数据 编辑:程序博客网 时间:2024/05/11 13:32

假设3位十进制数,目前,我所理解的抽屉是1001个这样的3位数里面一定会有两个相等,这一定是对的,但是,到目前为止,所有的程序中,我都是以如下方式处理:

for(i=1; i<12; i++){if(arr[i] == arr[0]){dis = i;break;}}

题目背景:


这显然不对,在这个程序当中,认定第一个数值在后面一定会重复出现,这在大部分情况下可行,却是错误的,下面一个设计用例就出现了问题:

对应代码为:

//Wrong answer #include<iostream>using namespace std;int main(){int n,m;int val;cin>>n;int arr[12];int dis;while(n--){cin>>m;m = m%10;val = m;int i;for(i=0; i<12; i++){arr[i] = val;val = val*m%10;}for(i=1; i<12; i++){if(arr[i] == arr[0]){dis = i;break;}}i = (m-1) % dis;cout<<arr[i]<<endl;}return 0;}
修改方案:
//12 6这一组数据怎么老是通不过 #include<iostream>using namespace std;int main(){int a,b,sum;int dis;int arr[11000];while(cin>>a>>b){if((a == 0)&&(b == 0)){return 0;}a = a % 1000;sum = a;for(int i=0; i<b; i++){arr[i] = sum;sum = sum * a % 1000;}cout<<arr[b - 1]<<endl;}return 0;}
这是很简单的处理方式,效率比较低。还有另外一种处理方式(尚待调试),算法思想是找出一个循环的长度以及循环开始的第一个数字:

//12 6这一组数据怎么老是通不过 #include<iostream>using namespace std;int getCircle(int arr[]){for(int i=0; i<1009; i++){for(int j=i + 1; j<1010; j++){if(arr[j] == arr[i]){return j - i;}}}return 0;}int main(){//int getCircle(int arr[], int *n);int a,b,sum;int dis;int arr[1010];while(cin>>a>>b){if((a == 0)&&(b == 0)){return 0;}a = a % 1000;sum = a;for(int i=0; i<1010; i++){arr[i] = sum;//cout<<arr[i]<<"";sum = sum * a % 1000;}//cout<<endl;  /*for(int i=0; i<1009; i++){for(int j=0; j<1010; j++){if(arr[i] == arr[0]){}}if(arr[i] == arr[0]){dis = i;//cout<<"我被执行了\n";//cout<<"dis"<<endl;break;}}*///int *st = 0;int cicleT = getCircle(arr);cout<<cicleT<<endl;dis = (b-1) % dis; cout<<arr[dis]<<endl;}return 0;}



原创粉丝点击