开学第四测
开学第四测(——qbxt zhw)
T1 (期望得分:100;实际得分:100)
消失的数字(number)
Time Limit:1000ms Memory Limit:128MB
题目描述
rsy拥有n个数,这n个数分别是a1,a2,…,an。
后来出现了一个熊孩子zhw,用橡皮擦去了其中若干个数字,并且打乱了剩下的数字。rsy赶到现场后只剩下了m个数字b1,b2,…,bm,她想知道哪些数字被擦去了。
现在你需要告诉rsy被擦去的n-m个数是什么。
输入格式(number.in)
第一行一个数n,第二行n个数ai,表示一开始的数字。
第三行一个数m,第四行m个数bi,表示被擦去后的数字。
输出格式(number.out)
一行n-m个数,从小到大输出所有被擦去的数字。
输入样例
5
1 3 5 7 8
3
3 5 8
输出样例
1 7
数据范围
对于30%的数据n<=1000,ai与bi都是有序的。
对于60%的数据n<=100000,ai与bi都是有序的。
对于80%的数据n<=100000,ai,bi<=n。
对于100%的数据n<=100000,1<=ai,bi<=10^9。
思路:输入数据后排序,两两比较;相同则比较下一个,否则输出
#include<algorithm> #include<iostream> #include<cstdio> #define N 100005 using namespace std; int n, m; int a[N], b[N]; int main() { // freopen("number.in","r",stdin); // freopen("number.out","w",stdout); scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); sort(a+1, a+n+1); scanf("%d", &m); for(int i = 1; i <= m; i++) scanf("%d", &b[i]); sort(b+1, b+m+1); int now = 1; for(int i = 1; i <= n; i++) { if(a[i] == b[now]) now++; else printf("%d ", a[i]); } // fclose(stdin); fclose(stdout); return 0; }
T2 (期望得分:50;实际得分:20)
一道数论好题(math)
Time Limit:1000ms Memory Limit:128MB
题目描述
rsy最近在研究欧几里得算法,不会的同学可以去看下课件以及代码……
现在她想到了一个新的问题,求k个数的最大公约数!
事实上这个问题仍然很简单。所以rsy想强化一下,她觉得最大公约数等于1就不是很有趣了。因此她想在n个数中找最多的数,使得它们的最大公约数不等于1。
现在rsy想知道,能找最多多少个数。
输入格式(math.in)
第一行一个数n。
第二行n个数ai。
输出格式(math.out)
一个数表示答案。
输入样例
5
2 3 4 5 6
输出样例
3
数据范围
对于30%的数据n<=5。
对于50%的数据n<=20。
对于80%的数据n<=1000,ai<=1000。
对于100%的数据1<=n<=100000,1<=ai<=100000,数据几乎是随机的。
思路:枚举 ( 1 , 100000 ] 间的每个数,定义一个变量记录可被输入数据整除的数的数量最多的 i
#include<algorithm> #include<iostream> #include<cstdio> #include<cmath> using namespace std; int n, maxn; int a[1000005]; int main() { freopen("math.in","r",stdin); freopen("math.out","w",stdout); scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); sort(a+1, a+n+1); for(int i = 1; i < n; i++) { if(a[i] == 1) continue; int sum = 1; for(int j = i+1; j <= n; j++) if(a[j]%a[i] == 0) sum++; if(sum > maxn) maxn = sum; } printf("%d", maxn); fclose(stdin); fclose(stdout); return 0; }
#include<iostream> #include<cstdio> #include<iomanip> #include<algorithm> #include<map> #define N 1000100 #define max(a,b) (a>b?a:b) #define ll long long using namespace std; int n,a[N],prime[N],v[N],tot,maxn,sum=0; map<ll,int> M; void altsn() { for(ll i=2;i<=maxn;i++) { if(v[N]==0){ prime[++tot]=i; }int tp=0; for(ll j=i;j<=maxn;j+=i) { if(j<=maxn && j>=0) { prime[j]=1; if(M[j] >= 1) { tp += M[j]; } } } sum=max(tp,sum); } } int main() { freopen("math.in","r",stdin); freopen("math.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; maxn=max(a[i],maxn);M[a[i]]++; }altsn(); cout<<sum; fclose(stdin);fclose(stdout); return 0; }
(其中用到了埃拉托斯特尼筛法来筛素数,详见:线性筛法求素数)
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; int n,A,a[1000005],now,MAX,i,j; int main() { freopen("math.in","r",stdin); freopen("math.out","w",stdout); scanf("%d", &n); for (i=1; i<=n; i++) { scanf("%d", &A); a[A]++; } for (i=2; i<=1000000; i++) { now=0; for (j=i; j<=1000000; j+=i) now += a[j]; MAX = max(MAX, now); } cout<<MAX; return 0; }
T3 (期望得分:e。。。不是0就行;实际得分:20)
扫雷(mine)
Time Limit:1000ms Memory Limit:128MB
题目描述
rsy最近沉迷于一款叫扫雷的游戏。
这个游戏是这样的。一开始网格上有n*m个位置,其中有一些位置有雷。每次rsy可以左键点击一个方块,此时若这个方块是雷,则rsy被炸,游戏结束,否则如果这个位置周围8格有x个雷,则会显示数字x。特别地,当x=0时,系统会自动左键点击附近8个位置。(此时附近8个位置一定没有雷,假如附近8个位置仍存在x=0,则继续往外扩展)想要更进一步获得关于题目的信息,打开程序->附近->游戏->扫雷或者直接打开下发的可执行文件。
或者rsy右键点击一个位置,标注这个位置是雷。
不幸的是,她鼠标不能左右键同时点击,因此只需考虑她左键点击与右键点击就可以了。
注意游戏胜利的条件是所有非雷的位置都被左键点击到。(特别地,当一开始时n*m个位置都是雷时,LYK自动获得胜利)
rsy从网上下载了金手指,很轻易地就掌握了所有雷所在的位置。rsy想通过最少的点击次数获得胜利(这里的点击次数不包括系统自动点击)。于是他来请求你的帮助。
输入格式(mine.in)
第一行两个数n,m。
接下来n行,每行m个数ai,j,表示这个矩阵。若ai,j=’*’则表示这个位置是雷,若ai,j=’.’则表示不是雷。
输出格式(mine.out)
一个数表示答案。
输入样例
3 3
..*
...
..*
输出样例
2
对于30%的数据n=1;
对于另外20%的数据n,m<=3;
对于再另外20%的数据 * 大致占矩阵的2/3且数据随机。
对于100%的数据n,m<=1000。
思路:搜索(BFS)
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<queue> #define N 1000 using namespace std; queue<int> q; int n, m; int sum, maxn, num; int map[N][N]; int vis[N][N]; string s; int dx[8] = {1, 1, 1, 0, -1, -1, -1, 0}; int dy[8] = {1, 0, -1, -1, -1, 0, 1, 1}; void dfs(int x, int y) { for(int i = 0; i < 8; i++) { int cx = x + dx[i], cy = y + dy[i]; if(map[cx][cy] == -1) continue; if(cx>=0 && cy>=0 && cx<n && cy<m && vis[cx][cy]==0) { vis[cx][cy] = 1; if(map[cx][cy] == 0) dfs(cx, cy); } } } int main() { freopen("mine.in","r",stdin); freopen("mine.out","w",stdout); scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { cin >> s; for(int j = 0; j < m; j++) { if(s[j] == '*') { map[i][j] = -1; if(map[i+1][j] != -1) map[i+1][j]++; if(map[i+1][j+1] != -1) map[i+1][j+1]++; if(map[i+1][j-1] != -1) map[i+1][j-1]++; if(map[i-1][j] != -1) map[i-1][j]++; if(map[i-1][j+1] != -1) map[i-1][j+1]++; if(map[i-1][j-1] != -1) map[i-1][j-1]++; if(map[i][j+1] != -1) map[i][j+1]++; if(map[i][j-1] != -1) map[i][j-1]++; } else if(s[j]=='.' && map[i][j]==0) map[i][j] = 0; } } for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(map[i][j]==0 && vis[i][j]==0) dfs(i, j), num++; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(vis[i][j]==0 && map[i][j]!=-1) num++; printf("%d", num); fclose(stdin); fclose(stdout); return 0; }
#include<algorithm> #include<iostream> #include<iomanip> #include<cstdio> #include<map> using namespace std; int n,m,ans,bom,que[1000000][2]; int a[1005][1005]; int mx[9]={0,0,0,1,1,1,-1,-1,-1}, my[9]={0,1,-1,0,1,-1,0,1,-1}; bool vis[1005][1005]; void Print(){ for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) cout<<a[i][j]<<" "; cout<<"\n"; } cout<<"\n\n\n\n"; } void bfs(int xx,int yy){ int h=1,t=1;que[1][0]=xx;que[1][1]=yy;vis[xx][yy]=1; while(h<=t){ int x=que[h][0],y=que[h][1]; for(int i=1;i<=8;i++){ int tx=mx[i]+x,ty=my[i]+y; if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]!=-1){ if(a[tx][ty]==0&&vis[tx][ty]==0){ que[++t][0]=tx;que[t][1]=ty; } } vis[tx][ty]=1; } ++h; } } int main() { freopen("mine.in","r",stdin); freopen("mine.out","w",stdout); cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { char x;cin>>x; if(x=='*') a[i][j]=-1,++bom; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]==-1){ if(a[i-1][j]!=-1) ++a[i-1][j]; if(a[i-1][j-1]!=-1) ++a[i-1][j-1]; if(a[i-1][j+1]!=-1) ++a[i-1][j+1]; if(a[i+1][j]!=-1) ++a[i+1][j]; if(a[i+1][j-1]!=-1) ++a[i+1][j-1]; if(a[i+1][j+1]!=-1) ++a[i+1][j+1]; if(a[i][j+1]!=-1) ++a[i][j+1]; if(a[i][j-1]!=-1) ++a[i][j-1]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(vis[i][j]==0&&a[i][j]==0) bfs(i,j);++ans; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(vis[i][j]==0&&a[i][j]!=-1) ++ans; cout<<ans; fclose(stdin);fclose(stdout); return 0; }
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <string> #include <cstring> using namespace std; int a[1005][1005],k,sum,X,n,m,i,j,sx[1000005],sy[1000005],L,R; bool v[1005][1005]; const int F1[8]= {-1,-1,-1,0,0,1,1,1}; const int F2[8]= {-1,0,1,-1,1,-1,0,1}; char s[1005][1005]; void dfs(int x, int y) { L=0; R=1; sx[1]=x; sy[1]=y; while (L!=R) { L++; if (!a[sx[L]][sy[L]] && s[sx[L]][sy[L]]=='.') for (int i=0; i<8; i++) if (!v[F1[i]+sx[L]][F2[i]+sy[L]]) { v[F1[i]+sx[L]][F2[i]+sy[L]]=true; sx[++R]=F1[i]+sx[L]; sy[R]=F2[i]+sy[L]; } } } int main() { freopen("mine.in","r",stdin); freopen("mine.out","w",stdout); scanf("%d%d",&n,&m); for (i=0; i<=n+1; i++) for (j=0; j<=m+1; j++) v[i][j]=true; for (i=1; i<=n; i++) for (j=1; j<=m; j++) v[i][j]=false; for (i=1; i<=n; i++) scanf("%s",s[i]+1); for (i=1; i<=n; i++) for (j=1; j<=m; j++) if (s[i][j]=='.') { X=0; for (k=0; k<8; k++) if (s[i+F1[k]][j+F2[k]]=='*') X++; a[i][j]=X; } for (i=1; i<=n; i++) for (j=1; j<=m; j++) if (!a[i][j] && s[i][j]=='.' && !v[i][j]) { sum++; v[i][j]=true; dfs(i,j); } for (i=1; i<=n; i++) for (j=1; j<=m; j++) if (s[i][j]=='.' && !v[i][j]) sum++; cout<<sum; return 0; }