韬韬抢苹果:
题目:
又到了收获的季节,树上结了许多韬韬,错了,是许多苹果,有很多个小韬韬都来摘苹果。每个韬韬都想要最大的苹果,所以发生了争执,为了解决他们的矛盾,出题人定了一项特殊的规则,按体重的大小来定顺序,每一轮都是先由胖的先摘(照顾胖子),每个韬韬都是很聪明的,不会错过眼前最大的苹果。现在问题来了,一共有n个苹果,m个韬韬,要你按原顺序输出每个韬韬可以抢到的苹果的总大小。
思路:大水题!!!直接模拟。
code:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long ll; 5 6 int n,m; 7 int app[100001]; 8 ll sum[100001]; 9 struct ozj { 10 int wei,num; 11 } tt[100001]; 12 13 bool cmd(int x,int y) { 14 return x>y; 15 } 16 bool cmp(ozj x,ozj y) { 17 return x.wei>y.wei; 18 } 19 int main() { 20 scanf("%d%d",&n,&m); 21 for(int i=1; i<=n; ++i) { 22 scanf("%d",&app[i]); 23 } 24 for(int i=1; i<=m; ++i) { 25 scanf("%d",&tt[i].wei); 26 tt[i].num=i; 27 } 28 sort(tt+1,tt+m+1,cmp); 29 sort(app+1,app+1+n,cmd); 30 int j=1; 31 for(int i=1; i<=n; ++i) { 32 if(j>m) { 33 j=1; 34 } 35 sum[tt[j].num]+=app[i]; 36 j++; 37 } 38 for(int i=1; i<=m; ++i) { 39 printf("%lld ",sum[i]); 40 } 41 return 0; 42 }
开场舞蹈:
题目:
在全世界人民的期盼下,2008年北京奥林匹克运动会终于隆重召开了!
为了展示中华民族博大精深的优秀传统文化,负责开幕式开场舞蹈的编排人员一丝不苟,每一个细节都力争完美。关于队伍是采用“天圆”阵还是“地方”阵的问题,大家讨论了七天七夜,仍没有结果。于是,他们希望借助计算机,计算两种阵型的成本。
队伍将排列在一个二维平面内,且必须以(0,0)点为中心使得队伍保持对称美。“天圆”阵是一个圆形,而“地方”阵则是一个边平行于坐标轴的正方形。由于某种因素,阵型要求覆盖某些点(可以在边上)。
你的任务是,计算出能够覆盖这些点的两种阵型的最小面积。
思路:
水题,不想讲。
code:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 using namespace std; 5 6 int n,x,y; 7 double pi=3.14; 8 long long max1=-1,max2=-1; 9 double ans1=-1; 10 long long ans2=-1; 11 double len; 12 13 int max(int x,int y) { 14 if(x>y) { 15 return x; 16 } 17 return y; 18 } 19 double maxn(double x,double y) { 20 if(x>y) { 21 return x; 22 } 23 return y; 24 } 25 bool cmp(int x,int y) { 26 return x>y; 27 } 28 int main() { 29 scanf("%d",&n); 30 for(int i=1; i<=n; i++) { 31 scanf("%d%d",&x,&y); 32 len=sqrt(abs(x)*abs(x)+abs(y)*abs(y)); 33 max1=max(max1,x); 34 max2=max(max2,y); 35 ans1=maxn(ans1,len); 36 } 37 ans2=max(max1,max2); 38 ans1=ans1*ans1*pi; 39 ans2=2*ans2*2*ans2; 40 printf("%.0lf\n%lld",ans1,ans2); 41 return 0; 42 }
架设电话线:
题目:
Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务。于是,FJ必须为此向电信公司支付一定的费用。
FJ的农场周围分布着N(1 <= N <= 1,000)根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连。一共P(1 <= P <= 10,000)对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接。
第i对电话线杆的两个端点分别为A_i、B_i,它们间的距离为L_i (1 <= L_i <= 1,000,000)。数据中保证每对{A_i,B_i}最多只出现1次。编号为1的电话线杆已经接入了全国的电话网络,整个农场的电话线全都连到了编号为N的电话线杆上。也就是说,FJ的任务仅仅是找一条将1号和N号电话线杆连起来的路径,其余的电话线杆并不一定要连入电话网络。
经过谈判,电信公司最终同意免费为FJ连结K(0 <= K < N)对由FJ指定的电话线杆。对于此外的那些电话线,FJ需要为它们付的费用,等于其中最长的电话线的长度(每根电话线仅连结一对电话线杆)。如果需要连结的电话线杆不超过K对,那么FJ的总支出为0。
请你计算一下,FJ最少需要在电话线上花多少钱。
思路:
二分答案,在判定是否可行时,只需要判断是否能寻找到一条路径,使得该路径上大于我们二分的这个值的边不超过k条,实质上就是最短路做的一个变形而已,小于二分的值的边可以看做边权为0,大于的可以看做边权为1,直接求最短路看是否小于k即可。
空间和时间可以不用优化(最好还是优化一下);
下面的代码有优化。
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #define N 2100 6 #define M 2100000 7 using namespace std; 8 int n,p,k; 9 int st[N+1],tot; 10 struct edge 11 { 12 int to,val,last; 13 }e[M<<1|1]; 14 void add(int a,int b,int c) 15 { 16 e[++tot].to=b; 17 e[tot].val=c; 18 e[tot].last=st[a]; 19 st[a]=tot; 20 } 21 struct node 22 { 23 int x,y; 24 }; 25 int dis[N+1][N+1]; 26 bool vis[N+1][N+1]; 27 int spfa() 28 { 29 queue<node> q; 30 q.push((node){1,0}); 31 memset(dis,0x3f,sizeof(dis)); 32 dis[1][0]=0; 33 while(!q.empty()) 34 { 35 node u=q.front(); 36 vis[u.x][u.y]=false; 37 q.pop(); 38 for(int i=st[u.x];i!=0;i=e[i].last) 39 { 40 int v=e[i].to; 41 if(max(dis[u.x][u.y],e[i].val)<dis[v][u.y]) 42 { 43 dis[v][u.y]=max(dis[u.x][u.y],e[i].val); 44 if(!vis[v][u.y]) 45 vis[v][u.y]=true,q.push((node){v,u.y}); 46 } 47 if(u.y<k&&dis[u.x][u.y]<dis[v][u.y+1]) 48 { 49 dis[v][u.y+1]=dis[u.x][u.y]; 50 if(!vis[v][u.y+1]) 51 vis[v][u.y+1]=true,q.push((node){v,u.y+1}); 52 } 53 } 54 } 55 int res=2147483647; 56 for(int i=0;i<=k;i++) 57 res=min(res,dis[n][i]); 58 return res; 59 } 60 int main() 61 { 62 scanf("%d %d %d",&n,&p,&k); 63 for(int i=1;i<=p;i++) 64 { 65 int a,b,c; 66 scanf("%d %d %d",&a,&b,&c); 67 add(a,b,c),add(b,a,c); 68 } 69 int ans=spfa(); 70 if(ans>11000000) 71 printf("-1"); 72 else 73 printf("%d",ans); 74 return 0; 75 }
水果店:
题目:
在一个市上,存在着很多的空地和住宅。现在,城市中新开了一个水果店,为了向城市居民问好,水果店决定派两个送货员向每一处住宅送一箱水果。由于一箱水果的重量很大,所以送货员每次只能携带一箱水果。
你可以把这个城市看成一个N行M列的棋盘,每个格子要么是空地,要么是住宅,要么是水果店。如果这个格子是一个空地,那就用0..9来表示这个空地的高度;如果是住宅,那么就用$来表示,如果是水果店,那么就用X来表示。从一个格子进入另一个格子,当且仅当两个格子相邻,也就是说共享一条边。
如果两个格子中有一个是住宅或水果店,那么需要花费2分钟的时间。
如果两个格子都是空地,那么就按高度来讨论时间。如果两个空地的高度相同,则花费1分钟的时间;如果两者的高度差1,则花费3分钟的时间;如果两者的高度超过1,那么不能互相进入。
现在,水果店的老板想知道,如果让整个城市的住宅都收到自己的水果,最短需要多少时间呢?如果永远无法送到,请输出-1。
思路:
先建一个网格图,跑一遍spfa(数据很小),预处理水果店到住宅所需的时间,乘上2,暴搜出最佳答案,在减去两个最长的时间即可。
要注意细节!!
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #define N 210 6 using namespace std; 7 const int dx[4]={1,-1,0,0}; 8 const int dy[4]={0,0,1,-1}; 9 int abs(int x){if(x<0)return -x;return x;} 10 char map[N+1][N+1]; 11 int sx,sy; 12 int tx[N+1],ty[N+1],cnt; 13 int st[N+1][N+1],tot; 14 struct edge 15 { 16 int x,y,last,val; 17 }e[N*N<<1|1]; 18 void add(int x,int y,int a,int b,int c) 19 { 20 e[++tot].x=a,e[tot].y=b; 21 e[tot].val=c; 22 e[tot].last=st[x][y]; 23 st[x][y]=tot; 24 } 25 int dis[N+1][N+1]; 26 bool vis[N+1][N+1]; 27 struct node 28 { 29 int x,y; 30 }; 31 void spfa() 32 { 33 queue<node> q; 34 q.push((node){sx,sy}); 35 memset(dis,0x3f,sizeof(dis)); 36 dis[sx][sy]=0; 37 while(!q.empty()) 38 { 39 node u=q.front(); 40 vis[u.x][u.y]=false; 41 q.pop(); 42 for(int i=st[u.x][u.y];i!=0;i=e[i].last) 43 { 44 node v=(node){e[i].x,e[i].y}; 45 if(dis[u.x][u.y]+e[i].val<dis[v.x][v.y]) 46 { 47 dis[v.x][v.y]=dis[u.x][u.y]+e[i].val; 48 if(!vis[v.x][v.y]) 49 vis[v.x][v.y]=true,q.push((node){v.x,v.y}); 50 } 51 } 52 } 53 } 54 bool flag[N+1]; 55 int ans=2147483647; 56 void dfs(int h) 57 { 58 int sum1=0,sum2=0,max1=0,max2=0; 59 for(int i=1;i<=cnt;i++) 60 { 61 if(flag[i]) 62 sum1+=dis[tx[i]][ty[i]]<<1,max1=max(max1,dis[tx[i]][ty[i]]); 63 else 64 sum2+=dis[tx[i]][ty[i]]<<1,max2=max(max2,dis[tx[i]][ty[i]]); 65 } 66 if(sum1==0) 67 ans=min(ans,sum2-max2); 68 if(sum2==0) 69 ans=min(ans,sum1-max1); 70 if(sum1!=0&&sum2!=0) 71 ans=min(ans,max(sum1-max1,sum2-max2)); 72 if(h>=cnt+1) 73 return; 74 flag[h]=true; 75 dfs(h+1); 76 flag[h]=false; 77 dfs(h+1); 78 } 79 int main() 80 { 81 // freopen("水果店.in","r",stdin); 82 int n,m; 83 scanf("%d %d",&n,&m); 84 for(int i=1;i<=n;i++) 85 scanf("%s",map[i]+1); 86 for(int i=1;i<=n;i++) 87 for(int j=1;j<=m;j++) 88 { 89 if(map[i][j]=='$') 90 tx[++cnt]=i,ty[cnt]=j; 91 if(map[i][j]=='X') 92 sx=i,sy=j; 93 for(int k=0;k<4;k++) 94 { 95 int dex=i+dx[k],dey=j+dy[k]; 96 if(dex<=0||dex>n||dey<=0||dey>m) 97 continue; 98 if(map[dex][dey]=='X'||map[dex][dey]=='$') 99 add(i,j,dex,dey,2),add(dex,dey,i,j,2); 100 else 101 if(abs((int)(map[dex][dey]-map[i][j]))==1) 102 add(i,j,dex,dey,3); 103 else 104 if(map[dex][dey]==map[i][j]) 105 add(i,j,dex,dey,1); 106 } 107 } 108 spfa(); 109 if(cnt==0) 110 { 111 printf("0"); 112 return 0; 113 } 114 for(int i=1;i<=cnt;i++) 115 if(dis[tx[i]][ty[i]]>10000000) 116 { 117 printf("-1"); 118 return 0; 119 } 120 // for(int i=1;i<=cnt;i++) 121 // printf("%d %d %d %d %d\n",sx,sy,tx[i],ty[i],dis[tx[i]][ty[i]]); 122 dfs(1); 123 printf("%d",ans); 124 return 0; 125 }
总结:
今天的题很水,很水,很水。但我只拿了226分,哎╮(╯▽╰)╭。
还要继续加油。