题目链接
https://codeforces.com/problemset/problem/887/B
解题思路
居然直接“暴力”?
看代码很好懂。
在这我就来分析一下为什么顶多产生两位数:
最小三位数为100,要产生别的三位数满足题意,就必须要能产生100,
所以我们来证明没法产生100,就证明出了没法产生任意三位数:
首先,一个或者两个正方体是没办法产生三位数的,所以不做讨论;
当存在三个正方体时,总共2 * 6 = 18个数,要想产生100,至少要满足,存在两个0以构成100,存在两个1以构成11,存在两个2以构成22,……,存在两个9以构成99,算一下发现这总共2 * 10 = 20个数,最多才能出现18个数,这显然不可能,所以产生不了100;
同样的,也不能产生99,要想产生99,至少要满足,存在一个0以构成10,20,30,……,90,存在两个1以构成11,存在两个2以构成22,……,存在两个9以构成99,总共19个数,依然大于18个,所以也产生不了99。
代码1是大佬的;
代码2是我这个fw的,想了2小时终于A了个1300的题,我笑了……
代码又丑又长就别看了,附上自己看的。
AC代码1
#include<bits/stdc++.h> using namespace std; const int N=20; const int M=100; int a[N],t,n; bool v[M]; int main() { cin>>n; for(int i=0;i<6*n;i++) cin>>a[i],v[a[i]]=1;//枚举每个数 for(int i=0;i<6*n;i++)for(int j=0;j<6*n;j++)if(i!=j && i/6!=j/6)v[a[i]*10+a[j]]=1;//若遍历的两个数不是同一个正方体上的且不是同一个正方体上的同一个数,就记录下这个两位数 while(v[++t]);cout<<t-1<<endl;//第一个停住的就是刚好没法构成的数,-1即答案 }
AC代码2
#include<bits/stdc++.h> using namespace std; int vis[10],cnt[10][10],a,n,num[10],pos[10],t[10]; int main() { cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=6;j++) cin>>a,cnt[i][a]=1,vis[a]=1; for(int i=1;i<=9;i++) if(!vis[i]) { cout<<i-1<<endl; return 0; } if(!vis[0]) { cout<<9<<endl; return 0; } for(int i=1;i<=n;i++) for(int j=0;j<=9;j++) { int f=0; for(int p=1;p<=n;p++) { if(p==i) continue; if(cnt[p][j]) f=1; } if(!f) pos[j]=i; } for(int j=1;j<=9;j++) for(int i=1;i<=n;i++) num[j]+=cnt[i][j]; for(int j=1;j<=9;j++) { memset(t,0,sizeof t); for(int p=1;p<=n;p++) { if(p==pos[j]) continue; for(int q=0;q<=9;q++) t[q]+=cnt[p][q]; } for(int q=0;q<=9;q++) { if(!t[q]) { cout<<j*10+q-1<<endl; return 0; } } if(num[j]<2) { cout<<j*10+j-1<<endl; return 0; } } return 0; }
总结
我一直在思考如何区别处理0与其他数;
看到大佬代码后,我直接崩溃了QWQ。