@Moritz
2019-03-26T04:26:10.000000Z
字数 6452
阅读 592
aoapc_2nd C++ 所有文稿
输入正整数n,从小到大的顺序输出所有形如abcde/fghij=n的表达式,其中a~j恰好为数字0-9的一个排列。
思路:即使参考了书上的思路,看上去很容易实现,实际上真正上手写出来代码花了几个多小时,再次深刻地体现了现在纸上写好细节思路的重要性,以及对应功能用函数实现使到代码简化的必要性。
/*19:48*//*21:04*/#include <iostream>#include <cmath>using namespace std;int a[20],n,cnt=0;int turn_5(int x=1,int y=5){//把除数(数组的前五个数)化成整数int tot=0;float e=0.0;for(int i=x;i<=y;i++){tot=tot+a[i]*pow(10,e);//printf("i=%d tot=%d\n",i,tot);e=e+1.0;}return tot;}int devi(int x,int n,int a=5){//把被除数拆成5个数字,以便判重int e=1;for(int i=1;i<n;i++) e*=10;x/=e;x=x%10;return x;}void find_5(int cur){//生成除数的所有可能/*递归边界,判重*/if (cur>5) {if (turn_5()*n<=99999) {bool ok=true;int x=turn_5()*n;for(int i=6;i<=10;i++){a[i]=devi(x,i-5,5);for(int j=1;j<i;j++){if (a[j]==a[i]){//printf("turn_5=%d x=%d a[%d]=a[%d]==%d\n",turn_5(),x,i,j,a[i]);ok=false;break;}}}if (ok){//如果不重复 输出if (cnt++)cout<<endl;for(int i=10;i>=6;i--) cout<<a[i];cout<<'\\';for(int i=5;i>=1;i--) cout<<a[i];cout<<'\='<<n;}}return;}/*生成除数的排列*/for(int i=0;i<=9;i++){bool ok=true;for(int j=1;j<cur;j++){if (a[j]==i){ok=false;break;}}if (ok){a[cur]=i;find_5(cur+1);}}}int main(){cin>>n;memset(a,0,sizeof(a));find_5(1);system("pause");return 0;}
出现的几个难题(自己挖的坑):
输入n个元素组成的序列S,找出一个乘积最大的连续子序列,如果最大的乘积不是正数,则输出0。(1<=n<=10,-10<=Si<=10)
思路:直接循环枚举,没啥难度,反而一开始还想多了,开始写solve递归函数……
/*21:32*//*21:44*/#include <iostream>using namespace std;long long max_mu=0;int a[20],n;int mu(int x,int y){int tot=1;for(int i=x;i<=y;i++) tot*=a[i];return tot;}int main(){int en=0;while(cin>>n){memset(a,0,sizeof(a));max_mu=0;for(int i=0;i<n;i++) cin>>a[i];for(int i=0;i<n-1;i++){for(int j=1;j<n;j++){if (j-i>=1){max_mu=(max_mu>mu(i,j)?max_mu:mu(i,j));}}}if(en++) cout<<endl;cout<<max_mu;}system("pause");return 0;}
写就是了
/*21:49*//*21:57*/#include <iostream>using namespace std;const int maxn=1000;int a[maxn],n;void print_per(int cur){if (cur>=n){cout<<"(";int co=0;for(int i=0;i<n;i++){if (co++) cout<<",";cout<<a[i];}cout<<")"<<endl;return;}for(int i=1;i<=n;i++){bool ok=true;for(int j=0;j<cur;j++){if (a[j]==i){ok=false;break;}}if(ok){a[cur]=i;print_per(cur+1);}}}int main(){cin>>n;print_per(0);system("pause");return 0;}
/*22:04*//*22:23*/#include <iostream>#include <algorithm>using namespace std;const int maxn=1000;int a[maxn],n,p[maxn],re[10];int count(int x,int cur){//优化int tot=0;for(int i=0;i<cur;i++){if (a[i]==x) tot++;}return tot;}void print_per(int cur){if (cur>=n){cout<<"(";int co=0;for(int i=0;i<n;i++){if (co++) cout<<",";cout<<a[i];}cout<<")"<<endl;return;}for(int i=0;i<=n;i++){//从p0-pn取值if (i==0||p[i]!=p[i-1]){//注意!!!:此举避免了出现重复的排列,例如(1,1,1)的情况if (count(p[i],cur)<re[p[i]]){//如果现有a元素中p元素各值的数量未满a[cur]=p[i];print_per(cur+1);}}}}int main(){cin>>n;memset(p,0,sizeof(p));memset(a,0,sizeof(a));memset(re,0,sizeof(re));for(int i=0;i<n;i++){cin>>p[i];re[p[i]]++;//优化书中代码,只需统计一次p中p[i]出现的次数}sort(p,p+n);print_per(0);system("pause");return 0;}
看了下,没怎么管。 -2019.3.8
看完分析之后试写了一下
/*10:14*//*10:58*/#include <iostream>#include <cstdio>#include <set>#include <map>#include <string>#include <utility>using namespace std;int a1[20],a2[20],cnt=0;pair<int,int> point[10];//存放皇后的坐标map<set<pair<int,int> > ,int> m;bool an1(int x,int y,int cur){//判断(x,y)点主对角线上是否有皇后/*if (a1[y-x+7]==0) return true;return false;*/for(int i=1;i<cur;i++){if (point[i].first+point[i].second==x+y) return false;}return true;}bool an2(int x,int y,int cur){//判断的对角线上是否有皇后/*if (a2[y+x]==0) return true;return false;*/for(int i=1;i<cur;i++){if (point[i].first-point[i].second==x-y) return false;}return true;}void search(int cur){if (cur>8){set<pair<int,int>> p;for(int i=1;i<=8;i++){p.insert(make_pair((point[i]).first,(point[i]).second));}if (!m.count(p)){m[p]=1;printf("Case %d\n",++cnt);for(int i=1;i<=8;i++){printf("Point %d:(%d,%d)\n",i,point[i].first,point[i].second);}}return;}for(int x=1;x<=8;x++){//确定x坐标bool ok_x=true;for(int i=1;i<cur;i++){//y坐标判重if ((point[i]).first==x){ok_x=false;break;}}if (ok_x){for(int y=1;y<=8;y++){bool ok_y=true;for(int j=1;j<cur;j++){//x坐标判重if ((point[j]).second==y){ok_y=false;break;}}if (ok_y){if (an1(x,y,cur)&&an2(x,y,cur)){point[cur].first=x;point[cur].second=y;search(cur+1);}}}}}}int main(){memset(a1,0,sizeof(a1));memset(a2,0,sizeof(a2));memset(point,0,sizeof(point));search(1);system("pause");return 0;}/*(输出的点和坐标已省略,共92组解Process returned 0 (0x0) execution time : 57.719 sPress any key to continue.*/
没有意识到,其实直接规定每行有一个皇后就可以了,不用进行y坐标的判重,算法复杂度明显提高,运行时间将近一分钟,并且还需要运用map进行判重。
优化之后:
/*2.1 去掉了map判重*/#include <iostream>#include <cstdio>#include <string.h>#include <utility>using namespace std;int cnt=0;pair<int,int> point[10];//存放皇后的坐标bool an1(int x,int y,int cur){//判断(x,y)点主对角线上是否有皇后for(int i=1;i<cur;i++){if (point[i].first+point[i].second==x+y) return false;}return true;}bool an2(int x,int y,int cur){//判断的对角线上是否有皇后for(int i=1;i<cur;i++){if (point[i].first-point[i].second==x-y) return false;}return true;}void search(int cur){if (cur>8){printf("Case %d\n",++cnt);for(int i=1;i<=8;i++){printf("Point %d:(%d,%d)\n",i,point[i].first,point[i].second);}return;}for(int y=1;y<=8;y++){bool ok_y=true;for(int j=1;j<cur;j++){//x坐标判重if ((point[j]).second==y){ok_y=false;break;}}if (ok_y){if (an1(cur,y,cur)&&an2(cur,y,cur)){point[cur].first=cur;point[cur].second=y;search(cur+1);}}}}int main(){memset(point,0,sizeof(point));search(1);system("pause");return 0;}/*至此,完成,11:11Process returned 0 (0x0) execution time : 0.156 sPress any key to continue.*/
一开始理解出现偏差,误以为第k小的困难串长度等于k,输入为30 3的时候输出错误,然后修改得乱七八糟
/*10:27*/#include <iostream>#include <string>using namespace std;int n,l;string str(80,'0'),str2(80,'0');//string初始化,否则str[cur-1]=c语句会造成溢出void solve(int cur){if (cur>n){cout<<str<<endl;system("pause");return;}else{for(int i=0;i<l;i++){char c='A'+i;bool ok=true;cout<<"enter loop cur="<<cur<<endl;for(int len=1;len<cur/2;len++){if (str.substr(cur-len)==str.substr(cur-len*2,len)){cout<<str.substr(cur-len)<<endl;cout<<str.substr(cur-len*2,len)<<endl;cout<<str<<endl;ok=false;break;}}cout<<"loop ok cur="<<cur<<endl;if (ok){str[cur-1]=c;solve(cur+1);}}}}int main(){cin>>n>>l;//solve(1);int cur=1,cnt=0;while(cnt<=n){bool ok=true;char c;for(int i=0;i<l;i++){c='A'+i;str2[cur-1]=c;//cout<<"enter loop cur="<<cur<<endl;ok=true;for(int len=1;len<=cur/2;len++){//cout<<str.substr(cur-len,len)<<endl;//cout<<str.substr(cur-len*2,len)<<endl;if (str2.substr(cur-len,len)==str2.substr(cur-len*2,len)){//cout<<str.substr(cur-len,len)<<endl;//cout<<str.substr(cur-len*2,len)<<endl;ok=false;break;}}if (ok) {//cout<<"loop ok cur="<<cur<<endl;cnt++;str[cur-1]=c;str2[cur-1]=c;}}cur++;}for(int i=0;i<cur;i++) cout<<str[i];system("pause");return 0;}/*运行结果:7 3CBBB0请按任意键继续. . .不改了,看书*/
书上照搬,发现30 3无输出
挖个坑先
2019.3.8