---恢复内容开始---
链接:https://www.nowcoder.com/acm/contest/93/B
来源:牛客网
B-wyh的矩阵
题目描述
给你一个n*n矩阵,按照顺序填入1到n*n的数,例如n=5,该矩阵如下
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
现在让你连接相邻两条边的中点,然后只保留他们围成封闭图形区域的数字,那么这个矩阵变为
3 |
||||
7 |
8 |
9 |
||
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
||
23 |
现在你们涵哥让你求变化后的矩阵的所有元素的和为多少
输入描述:
输入第一行一个整数T(1<=T<=100)
接下来有T组测试数据,每组测试数据输入一个整数n(3<=n<=10000)
保证输入的n为奇数
输出描述:
对于每组测试数据,输出对应答案
输入
2 3 5
输出
25 169
找规律,每一行取中间的1,3,5.....maxn....5,3,1个数,就是最中间那个数的1,3,5...倍数,每次累加即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 int main() 5 { 6 LL n,i,j,k=0,s=0,l,r; 7 int t; 8 cin>>t; 9 while(t--){ 10 cin>>n; 11 s=0; 12 LL tt=n/2+1,h=1; 13 for(i=1;i<=n/2+1;++i){ 14 s+=tt*h; 15 //cout<<tt*h<<endl; 16 h+=2; 17 tt+=n; 18 } 19 h-=4; 20 //tt+=n; 21 for(i=n/2+2;i<=n;++i){ 22 s+=tt*h; 23 // cout<<tt*h<<endl; 24 h-=2; 25 tt+=n; 26 } 27 cout<<s<<endl; 28 } 29 30 return 0; 31 }
链接:https://www.nowcoder.com/acm/contest/93/D
来源:牛客网
题目描述
给你一个n*m的迷宫,这个迷宫中有以下几个标识:
s代表起点
t代表终点
x代表障碍物
.代表空地
现在你们涵哥想知道能不能从起点走到终点不碰到障碍物(只能上下左右进行移动,并且不能移动到已经移动过的点)。
输入描述:
输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每一组测试数据,第一行输入2个数n和m(1<=n,m<=500)
接下来n行,每行m个字符代表这个迷宫,每个字符都是上面4个中的一种
数据保证只有一个起点和一个终点
输出描述:
对于每一组测试数据,如果可以的话输出YES,不可以的话输出NO
输入
1 3 5 s...x x...x ...tx
输出
YES
直接深搜一遍就好了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 char e[550][550]; 5 bool vis[510][510]; 6 int fx[4][2]={1,0,0,1,-1,0,0,-1}; 7 int n,m; 8 void dfs(int x,int y) 9 { 10 vis[x][y]=1; 11 for(int i=0;i<4;++i){ 12 int dx=x+fx[i][0]; 13 int dy=y+fx[i][1]; 14 if(dx<1||dx>n||dy<1||dy>m||vis[dx][dy]==1||e[dx][dy]=='x') continue; 15 dfs(dx,dy); 16 } 17 } 18 int main() 19 { 20 int t,i,j,k; 21 cin>>t; 22 while(t--){int sx,sy,tx,ty; 23 cin>>n>>m; 24 for(i=1;i<=n;++i) scanf("%s",e[i]+1); 25 for(i=1;i<=n;++i){ 26 for(j=1;j<=m;++j){//cin>>e[i][j]; 27 //scanf("%c",&e[i][j]); 28 if(e[i][j]=='s'){ 29 sx=i; 30 sy=j; 31 } 32 else if(e[i][j]=='t'){ 33 tx=i; 34 ty=j; 35 } 36 } 37 } 38 memset(vis,0,sizeof(vis)); 39 dfs(sx,sy); 40 vis[tx][ty]?puts("YES"):puts("NO"); 41 } 42 return 0; 43 }
链接:https://www.nowcoder.com/acm/contest/93/E
来源:牛客网
题目描述
这个问题很简单,就是问你n的阶乘末尾有几个0?
输入描述:
输入第一行一个整数T(1<=T<=100),代表测试组数
接下来T行,每行一个数n(1<=n<=10^9)
输出描述:
对于每组测试数据,输出对应答案
输入
5 1 2 3 4 5
输出
0 0 0 0 1
经典题目,统计因子5的个数即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 int f(int n){ 5 int tt=5,s=0; 6 while(n/tt){ 7 s+=n/tt; 8 tt*=5; 9 } 10 return s; 11 } 12 int main() 13 { 14 int t,n,i,j; 15 cin>>t; 16 while(t--){ 17 cin>>n; 18 cout<<f(n)<<endl; 19 } 20 return 0; 21 }
链接:https://www.nowcoder.com/acm/contest/93/F
来源:牛客网
题目描述
你们wyh学长给你n个点,让你分成2个集合,然后让你将这n个点进行两两连接在一起,连接规则是这样的
1. 连接的两个点必须在不同的两个集合
2. 一个集合内部任意两个点之间不能相连
现在,wyh学长需要让你将这n个点任意分成2个集合之后,最多能连接多少条边?
输入描述:
输入第一行一个整数T(1<=T<=100000)
接下来T组测试数据,每组测试数据输入一个整数n(1<=n<=100000)
输出描述:
对于每组测试数据,输出对应答案
输入
4 0 1 2 4
输出
0 0 1 4
说明
对于4的情况,设4个点为A,B,C,D
第一个集合元素为 A,B
第二个集合元素为C,D
连接的边为AC,AD,BC,BD
此时为最大情况,所以答案为4
贪心,分成两个大小最接近的数即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 int main() 5 { 6 LL n,i,j,t; 7 cin>>t; 8 while(t--){ 9 scanf("%lld",&n); 10 printf("%lld ",(n/2)*(n-n/2)); 11 } 12 return 0; 13 }
链接:https://www.nowcoder.com/acm/contest/93/I
来源:牛客网
题目描述
wyh学长现在手里有n个物品,这n个物品的重量和价值都告诉你,然后现在让你从中选取k个,问你在所有可能选取的方案中,最大的单位价值为多少(单位价值为选取的k个物品的总价值和总重量的比值)
输入描述:
输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每组测试数据,第一行输入两个数n和k(1<=k<=n<=100000)
接下来有n行,每行两个是a和b,代表这个物品的重量和价值
输出描述:
对于每组测试数据,输出对应答案,结果保留两位小数
输入
1 3 2 2 2 5 3 2 1
输出
0.75
说明
对于样例来说,我们选择第一个物品和第三个物品,达到最优目的
经典的分数规划,二分这个最优解,对于满足条件x的一组物品{(v1,w1),(v2,w2)......(vk,wk)}一定满足:
SUM{v}/sum{w}>=x,即(v1-x*w1)+(v2-x*w2)+...+(vk-x*wk)>=0,显然我们对于每一个x,可以先处理出p[i]=v[i]-x*w[i]的数组,然后选择前k大的元素检查。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-6 4 double w[100010],v[100010],p[100010]; 5 int n,k; 6 bool ok(double x){ 7 for(int i=1;i<=n;++i){ 8 p[i]=v[i]-x*w[i]; 9 } 10 sort(p+1,p+1+n,greater<double>()); 11 double s=0; 12 for(int i=1;i<=k;++i) 13 s+=p[i]; 14 return s>=0; 15 } 16 int main() 17 { 18 int i,j; 19 int t; 20 cin>>t; 21 while(t--){ 22 cin>>n>>k; 23 for(i=1;i<=n;++i){ 24 scanf("%lf%lf",w+i,v+i); 25 } 26 double l=0,r=100010; 27 while(abs(l-r)>=eps){ 28 double m=r-(r-l)/2; 29 if(ok(m)){ 30 l=m; 31 } 32 else{ 33 r=m; 34 } 35 } 36 printf("%.2f ",l); 37 } 38 return 0; 39 }
链接:https://www.nowcoder.com/acm/contest/93/K
来源:牛客网
题目描述
wyh学长特别喜欢斐波那契数列,F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n>=2)
一天他突发奇想,想求F(a^b)%c
输入描述:
输入第一行一个整数T(1<=T<=100),代表测试组数
接下来T行,每行三个数 a,b,c (a,b<=2^64) (1<c<1000)
输出描述:
输出第a^b项斐波那契数对c取余的结果
输入
3 1 1 2 2 3 1000 32122142412412142 124124124412124 123
输出
1 21 3
找循环节。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL unsigned long long 4 LL f[1001000]; 5 LL qpow(LL a,LL b,LL c){ 6 LL r=1; 7 while(b){ 8 if(b&1) r=r*a%c; 9 a=a*a%c; 10 b>>=1; 11 } 12 return r; 13 } 14 int main() 15 { 16 LL t,a,b,c,i,j,k; 17 cin>>t; 18 while(t--){ 19 cin>>a>>b>>c; 20 LL tot; 21 f[0]=0,f[1]=1; 22 for(i=2;i<=1001000;++i){ 23 f[i]=(f[i-1]+f[i-2])%c; 24 if(f[i-1]==0&&f[i]==1){ 25 tot=i-1; 26 break; 27 } 28 } 29 cout<<f[qpow(a%tot,b,tot)]<<endl; 30 } 31 return 0; 32 }
链接:https://www.nowcoder.com/acm/contest/93/L
来源:牛客网
题目描述
你们wyh学长小时候住在河边,因为周围的生态环境非常好,所以经常会有天鹅浮在湖面上,每只天鹅都长得不一样,它们偶尔排成一排,偶尔分散开,偶尔也会去其他河畔,wyh学长为了统计它们的个数,编了一个程序赋予它们一个“萌”值,但是这些天鹅很不听话,一会儿会从别的地方游过来一两只,一会儿又会在统计过程中游走一两只,现在请你帮他完成统计任务。
输入描述:
共有T(T<=10)组数据,每组数据第一行为两个数 N, M (N,M <= 500000),代表有N只天鹅和M次操作,接下来一行是N个数字,下面M行首先会输入一个字符串S,接着会有三类操作,如果S是“insert”,接着输入一个正整数a,代表插入一只“萌”值为a的天鹅,如果S是“delete”,接着输入一个正整数a,代表删除一只“萌”值为a的天鹅,如果S是“query”,接着输入一个正整数k,代表查询“萌”值第k大的天鹅。
萌值为[1,1000000000],并且保证一定存在第k大
输出描述:
对应每次询问,输出询问结果。
输入
1 5 4 6 4 2 9 1 query 2 insert 7 delete 6 query 2
输出
6 7
值域线段树跑一波。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 int sumn[4000000],ch[4000000][2],tot; 5 void insert(int id,int L,int R,int a){ 6 int M=(L+R)/2; 7 if(L==R){ 8 sumn[id]++; 9 return; 10 } 11 if(a<=M){ 12 if(!ch[id][0]) ch[id][0]=tot++; 13 insert(ch[id][0],L,M,a); 14 } 15 else{ 16 if(!ch[id][1]) ch[id][1]=tot++; 17 insert(ch[id][1],M+1,R,a); 18 } 19 sumn[id]=sumn[ch[id][0]]+sumn[ch[id][1]]; 20 } 21 22 void delet(int id,int L,int R,int a){ 23 int M=(L+R)/2; 24 if(L==R){ 25 sumn[id]--; 26 return; 27 } 28 if(a<=M){ 29 //if(!ch[id][0]) ch[id][0]=tot++; 30 delet(ch[id][0],L,M,a); 31 } 32 else{ 33 // if(!ch[id][1]) ch[id][1]=tot++; 34 delet(ch[id][1],M+1,R,a); 35 } 36 sumn[id]=sumn[ch[id][0]]+sumn[ch[id][1]]; 37 } 38 39 int query(int id,int L,int R,int a){ 40 //cout<<L<<' '<<R<<' '<<sumn[id]<<endl; 41 int M=(L+R)/2; 42 if(L==R){ 43 return L; 44 } 45 if(sumn[ch[id][1]]>=a){ 46 return query(ch[id][1],M+1,R,a); 47 } 48 else 49 return query(ch[id][0],L,M,a-sumn[ch[id][1]]); 50 } 51 int main() 52 { 53 int t,n,m,i,j,k; 54 int a,b,c; 55 char s[100]; 56 cin>>t; 57 while(t--){ 58 cin>>n>>m; 59 memset(sumn,0,sizeof(sumn)); 60 memset(ch,0,sizeof(ch)); 61 tot=2; 62 for(i=1;i<=n;++i){ 63 scanf("%d",&a); 64 insert(1,1,1000000000,a); 65 } 66 while(m--){ 67 scanf("%s%d",s,&a); 68 if(!strcmp(s,"query")){ 69 printf("%d ",query(1,1,1000000000,a)); 70 } 71 else if(!strcmp(s,"insert")){ 72 insert(1,1,1000000000,a); 73 } 74 else { 75 delet(1,1,1000000000,a); 76 } 77 } 78 } 79 return 0; 80 }