8.25重庆南开CSP信心赛
A.填数字
时间限制:1s
空间限制:128MB
题面描述
信竞队的同学们在一个N*N的方格矩阵上填数字。开始时,所有矩阵里的数字都
是0。 同学们一共给 个子矩阵填了数字,每次填的数都是从 这区间中
选一个数字,然后给对应矩阵全部填上该数字。比如:
第1步,选了一个子矩阵,将数字2填上:
2 2 2 0
2 2 2 0
2 2 2 0
0 0 0 0
第2步,选了一个子矩阵,将数字7填上:
2 2 2 0
2 7 7 7
2 7 7 7
0 0 0 0
第3步,选了一个子矩阵,将数字3填上:
2 2 3 0
2 7 3 7
2 7 7 7
按此规则填下去,直到1到 中每个数字都被使用过一次(每个数字只能被使用
一次)。 现在给出最终的矩阵,但同学们已忘记第一步是选的哪个数子来填的。
请你帮忙计算第1步填的数字可能是哪些?输出第一步填写可能的数字的个数。
输入格式
第一行,一个整数N 接下来一个N*N的数字矩阵,表示填写结束时,矩阵的样
子。
输出格式
一个整数,表示第一步填可能的数字个数。
样例输入1
4 2
2 3 0
2 7 3 7
2 7 7 7
0 0 0 0
样例输出1
14
样例输入2
4 0
0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
样例输出2
15
数据范围与约定
对于40% 的数据,保证n<=50
对于 100%的数据,保证 n<=1000
考察点:二阶差分
对于每个数字统计出现的最上u,最下d,最左l,最右r的位置,然后就能框出一个矩形,把
以(u,l)(d,r)为对角线的矩阵整体加1,表示有一个矩形在这个位置至少涂了一次 最后,如果
一个格子的值>1,说明有超过一个矩形在这里涂了数字,那么这个格子最终的数字一定不能
最先涂 剩下的就是能最先涂的数字。 特殊情况:n≠1且最终矩阵里除了0外只有一种数字,
那么这个数字肯定不能先涂,要从答案中扣除。
1 //fread快读快写,快的一批 2 3 #include<stdio.h> 4 #include<bits/stdc++.h> 5 using namespace std; 6 inline char nc() 7 { 8 static char buf[100000],*p1=buf,*p2=buf; 9 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 10 } 11 inline int rd() 12 { 13 char ch=nc(); 14 int sum=0; 15 while(!(ch>=‘0‘&&ch<=‘9‘))ch=nc(); 16 while(ch>=‘0‘&&ch<=‘9‘)sum=sum*10+ch-48,ch=nc(); 17 return sum; 18 } 19 #define I_int int 20 char F[ 200 ] ; 21 inline void write( I_int x ) 22 { 23 I_int tmp = x > 0 ? x : -x ; 24 if( x < 0 ) putchar( ‘-‘ ) ; 25 int cnt = 0 ; 26 while( tmp > 0 ) 27 { 28 F[ cnt ++ ] = tmp % 10 + ‘0‘ ; 29 tmp /= 10 ; 30 } 31 while( cnt > 0 ) putchar( F[ -- cnt ] ) ; 32 } 33 #undef I_int 34 int a[1005][1005]; 35 int cn[1005][1005],Cnt[1005][1005]; 36 int x_min[1000005],x_max[1000005],y_min[1000005],y_max[1000005]; 37 int s[1005][1005]; 38 int cnt; 39 bool mark[1000005]; 40 bool mark2[1000005]; 41 int n; 42 int main() 43 { 44 45 int i,j,k; 46 n=rd(); 47 for(i=1; i<=n*n; i++) x_min[i]=y_min[i]=1e9; 48 for(i=1; i<=n; i++) 49 { 50 for(j=1; j<=n; j++) 51 { 52 a[i][j]=rd(); 53 if(a[i][j]!=0) 54 { 55 x_min[a[i][j]]=min(x_min[a[i][j]],i); 56 x_max[a[i][j]]=max(x_max[a[i][j]],i); 57 y_min[a[i][j]]=min(y_min[a[i][j]],j); 58 y_max[a[i][j]]=max(y_max[a[i][j]],j); 59 if(!mark[a[i][j]]) 60 { 61 cnt++; 62 mark[a[i][j]]=true; 63 } 64 } 65 } 66 } 67 if(cnt==0) 68 { 69 write(n*n); 70 return 0; 71 } 72 if(cnt==1) 73 { 74 write(n*n-1); 75 return 0; 76 } 77 for(i=1; i<=n*n; i++) 78 { 79 if(mark[i]) 80 { 81 cn[x_min[i]][y_min[i]]+=1; 82 cn[x_max[i]+1][y_min[i]]-=1; 83 cn[x_min[i]][y_max[i]+1]-=1; 84 cn[x_max[i]+1][y_max[i]+1]+=1; 85 } 86 } 87 int tot=0; 88 for(i=1; i<=n; i++) 89 { 90 for(j=1; j<=n; j++) 91 { 92 Cnt[i][j]=cn[i][j]+Cnt[i-1][j]+Cnt[i][j-1]-Cnt[i-1][j-1]; 93 if(Cnt[i][j]>1) 94 { 95 if(mark2[a[i][j]]==false) 96 { 97 mark2[a[i][j]]=true; 98 tot++; 99 } 100 } 101 } 102 } 103 write(n*n-tot); 104 }
B.路径数
时间限制: 1s
空间限制: 512MB
题目描述
给出一个N个节点的树,节点编号1到N,其中1号点为根。每个节点都有一个权
值。我们需要找出一条路径,要求该路径经过的节点权值总和等于L。同时要
求,该路径中不能有深度相同的节点。问,满足条件的路径有多少条?
输入格式
第一行是两个整数N和L。
第二行是N个正整数,第i个整数表i号节点的权值。
接下来的N-1行每行是2个整数x和y,表示x是y的父亲。
输出格式
一个整数,表示满足条件的路径方案数
样例输入1:
3 3
1 2 3
1 2
1 3
样例输出1:
2
数据规模
对于100%的数据N<=100000,所有权值以及S都不超过1000。
1 // luogu-judger-enable-o2 2 #include<stdio.h> 3 #include<bits/stdc++.h> 4 using namespace std; 5 struct node 6 { 7 int to; 8 int next; 9 }edge[1000000]; 10 int num,head[100005]; 11 int n,s; 12 long long ans; 13 int a[100005],fa[100005][21],w[100005][21]; 14 inline void add(int x,int y) 15 { 16 edge[++num].to=y; 17 edge[num].next=head[x]; 18 head[x]=num; 19 } 20 inline void dfs(int x,int dad) 21 { 22 fa[x][0]=dad; 23 w[x][0]=a[x]; 24 for(int i=1;i<=20;i++) 25 { 26 fa[x][i]=fa[fa[x][i-1]][i-1]; 27 w[x][i]=w[x][i-1]+w[fa[x][i-1]][i-1]; 28 } 29 int p=x,len=s; 30 for(int i=20;i>=0;i--) 31 if(fa[p][i]&&w[p][i]<len) 32 { 33 len-=w[p][i]; 34 p=fa[p][i]; 35 } 36 if(len==w[p][0])ans++; 37 for(int i=head[x];i;i=edge[i].next) 38 if(edge[i].to!=dad)dfs(edge[i].to,x); 39 } 40 int main() 41 { 42 ios::sync_with_stdio(false); 43 cout.tie(NULL); 44 cin>>n>>s; 45 for(int i=1;i<=n;i++) 46 cin>>a[i]; 47 int x,y; 48 for(int i=1;i<n;i++) 49 { 50 cin>>x>>y; 51 add(x,y); 52 add(y,x); 53 } 54 dfs(1,0); 55 cout<<ans; 56 } 57
C旅店 |
||
|
问题描述
一条笔直的公路旁有N家旅店,从左往右编号1到N,其中第i家旅店的位置坐标为。
旅人何老板总在赶路。他白天最多行走个单位的距离,并且夜间必须到旅店休息。
何老板给你Q个询问,每个询问的都由两个整数构成,其中第i个询问的格式为,,表示他想知道自己从号旅店走到号旅店,最少需要花费多少天?
输入格式
第一行,一个整数N
第二行,N个空格间隔的整数 表示每个旅店的坐标
第三行,一个整数L
第四行,一个整数Q
接下来Q行,每行两个整数,表示一次询问
输出格式
Q行,每行一个整数,依次表示对应询问的答案
样例输入
9
1 3 6 13 15 18 19 29 31
10
4
1 8
7 3
6 7
8 5
样例输出
4
2
1
2
提示
对于100%的数据:
2<=N<=10^5
1<=L<=10^9
1<=Q<=10^5
1<=X1<=X2...<=Xn<=10^9
X(i+1)-Xi<=L
Ai != Bi
原文地址:https://www.cnblogs.com/CXYscxy/p/11408590.html