NOIP模拟赛
题目背景
此题约为NOIP提高组Day1T1难度。
题目描述
B君站在一个n\times nn×n的棋盘上。最开始,B君站在(1,1)
这个点,他要走到(n,n)
这个点。
B君每秒可以向上下左右的某个方向移动一格,但是很不妙,C君打算阻止B君的计划。
每秒结束的时刻,C君会在(x,y)
上摆一个路障。B君不能走在路障上。
B君拿到了C君准备在哪些点放置路障。所以现在你需要判断,B君能否成功走到(n,n)
。
保证不会走到某处,然后被一个路障砸死。
输入输出格式
输入格式:
首先是一个正整数T
,表示数据组数。
对于每一组数据:
第一行,一个正整数n
。
接下来2n-2
行,每行两个正整数x
和y
,意义是在那一秒结束后,(x,y)
将被摆上路障。
输出格式:
对于每一组数据,输出Yes
或No
,回答B君能否走到(n,n)
。
输入输出样例
说明
样例解释:
以下0
表示能走,x
表示不能走,B
表示B君现在的位置。从左往右表示时间。
Case 1:
0 0 0 0 0 B (已经走到了)
B 0 x B x 0
Case 2:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 x 0 0 0 0 x 0 0 0 0 x 0 0
0 0 0 0 0 0 0 0 0 0 0 0 x 0 0 0 0 x 0 0
B 0 0 0 0 0 B 0 0 0 0 0 B 0 0 0 0 x B 0 ......(B君可以走到终点)
数据规模:
防止骗分,数据保证全部手造。
对于20%
的数据,有n<=3
。
对于60%
的数据,有n<=500
。
对于100%
的数据,有n<=1000
。
对于100%
的数据,有T<=10
。
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int T,n,tot; int vis[1001][1001]; int x[2001],y[2001]; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int bfs(int sx,int sy){ vis[sx][sy]=1;tot=0; queue<int>que1,que2; que1.push(sx);que2.push(sy); while(!que1.empty()){ int nowx=que1.front(); int nowy=que2.front(); que1.pop();que2.pop(); for(int i=0;i<4;i++){ int cx=nowx+dx[i]; int cy=nowy+dy[i]; if(cx>=1&&cx<=n&&cy>=1&&cy<=n&&!vis[cx][cy]){ vis[cx][cy]=1; que1.push(cx);que2.push(cy); if(cx==n&&cy==n) return 1; } } vis[x[++tot]][y[tot]]=1; } return 0; } int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=2*n-2;i++) scanf("%d%d",&x[i],&y[i]); if(bfs(1,1)) printf("Yes\n"); else printf("No\n"); memset(vis,0,sizeof(vis)); } }
题目背景
此题约为NOIP提高组Day2T1难度。
题目描述
在n\*n
的格子上有m
个地毯。
给出这些地毯的信息,问每个点被多少个地毯覆盖。
输入输出格式
输入格式:
第一行,两个正整数n、m
。意义如题所述。
接下来m
行,每行两个坐标(x1,y1)
和(x2,y2)
,代表一块地毯,左上角是(x1,y1)
,右下角是(x2,y2)
。
输出格式:
输出n
行,每行n
个正整数。
第i
行第j
列的正整数表示(i,j)
这个格子被多少个地毯覆盖。
输入输出样例
说明
样例解释
0 0 0 0 0 0 0 0 0 0 0 1 1 1 0
0 1 1 0 0 0 1 1 0 0 0 1 1 0 0
0 1 1 0 0 -> 0 1 2 1 1 -> 0 1 2 1 1
0 0 0 0 0 0 0 1 1 1 0 0 1 1 1
0 0 0 0 0 0 0 1 1 1 0 0 1 1 1
数据范围
对于20%
的数据,有n<=50
,m<=100
。
对于100%
的数据,有n<=1000
,m<=1000
。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; int map[1001][1001]; int main(){ scanf("%d%d",&n,&m); for(int k=1;k<=m;k++){ int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); for(int i=x1;i<=x2;i++) for(int j=y1;j<=y2;j++) map[i][j]++; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) printf("%d ",map[i][j]); printf("\n"); } }
题目背景
此题约为NOIP提高组Day2T2难度。
题目描述
众所周知,模数的hash会产生冲突。例如,如果模的数p=7
,那么4
和11
便冲突了。
B君对hash冲突很感兴趣。他会给出一个正整数序列value[]
。
自然,B君会把这些数据存进hash池。第value[k]
会被存进(k%p)
这个池。这样就能造成很多冲突。
B君会给定许多个p
和x
,询问在模p
时,x
这个池内数的总和
。
另外,B君会随时更改value[k]
。每次更改立即生效。
保证1<=p<n1<=p<n.
输入输出格式
输入格式:
第一行,两个正整数n,m
,其中n
代表序列长度,m
代表B君的操作次数。
第一行,n
个正整数,代表初始序列。
接下来m
行,首先是一个字符cmd
,然后是两个整数x,y
。
-
若
cmd='A'
,则询问在模x
时,y
池内数的总和。 -
若
cmd='C'
,则将value[x]
修改为y
。
输出格式:
对于每个询问输出一个正整数,进行回答。
输入输出样例
说明
样例解释
A 2 1
的答案是1+3+5+7+9=25
.
A 3 1
的答案是20+4+7+10=41
.
A 5 0
的答案是1+10=11
.
数据规模
对于10%
的数据,有n<=1000,m<=1000
.
对于60%
的数据,有n<=100000.m<=100000
.
对于100%
的数据,有n<=150000,m<=150000
.
保证所有数据合法,且1<=value[i]<=1000
.
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m,ans; int val[150010]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&val[i]); for(int i=1;i<=m;i++){ char s[10];int x,y; cin>>s>>x>>y; if(s[0]=='A'){ for(int j=y;j<=n;j+=x) ans+=val[j]; printf("%d\n",ans);ans=0; } else if(s[0]=='C') val[x]=y; } }
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; int val[150010]; int ans[1010][1010]; int gets(int x,int y){ if(x<=sqrt(n)) return ans[x][y]; else { int bns=0; for(int q=y;q<=n;q+=x) bns+=val[q]; return bns; } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&val[i]); /*for(int i=1;i<=m;i++){ char s[10];int x,y; cin>>s>>x>>y; if(s[0]=='A'){ for(int j=y;j<=n;j+=x) ans+=val[j]; printf("%d\n",ans);ans=0; } else if(s[0]=='C') val[x]=y; }*/ for(int p=1;p<=sqrt(n);p++) for(int i=1;i<=n;i++) ans[p][i%p]+=val[i]; for(int i=1;i<=m;i++){ char s[10];int x,y; cin>>s>>x>>y; if(s[0]=='A') printf("%d\n",gets(x,y)); else if(s[0]=='C'){ for(int p=1;p<=sqrt(n);p++) ans[p][x%p]=ans[p][x%p]-val[x]+y; val[x]=y; } } }