codevs 搜索题汇总(黄金级)
Posted 月沫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 搜索题汇总(黄金级)相关的知识,希望对你有一定的参考价值。
众所周知,LOL这款伟大的游戏,有个叫盖伦的英雄。他的伟大之处在于他特别喜欢蹲草丛阴人(XL:蹲草阴人也算英雄?!CZQ:没办法,个个都是这么玩的)。某日,德玛西亚与诺克萨斯之间又发生了一场战斗,嘉文四世希望盖伦能带领一支K人的德玛西亚军队出战。
战斗发生在召唤师峡谷。整个召唤师峡谷被分割成M行N列的一个矩阵,矩阵中有空地和几片草丛。这几片草丛中有些很大、有些很小。一个1×1的草丛能容纳3个士兵,盖伦坚信蹲草偷袭战术能战胜诺克萨斯军队,所以他希望他的军队能全部蹲进草丛里。当然,为了不影响盖伦的作战,盖伦需要单独霸占连起来的一片草丛(不管草丛有多大)。
第一行M、N、K,表示矩阵的行数、列数和士兵数量。
接下来M行,输入矩阵,\'.\'代表平地,\'*\'代表草丛。
如果德玛西亚军队和盖伦都能躲进草丛里,则输出“Demacia Win!”,否则输出“Demacia Lose!”
3 3 6
.**
...
.*.
Demacia Win!
1<=m、n<=1500
1<=k<=1500
P.S:这里对于两个1×1的草丛是否连在一起的定义是:对于每个1×1的草从,它与周围(上下左右)的草丛是连在一起的。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int m,n,k; int a[1500+10][1500+10]; int dis[1001]; int s[1000]; int head=0,tail=1; int x[1500+10],y[1500+10],qian[1500+10]; int x0[5]={0,0,0,1,-1},y0[5]={0,1,-1,0,0}; int p=0; bool f=false; void init() { scanf("%d%d%d",&m,&n,&k); getchar(); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { char c; scanf("%c",&c); if(c==\'.\') a[i][j]=0; else a[i][j]=1; } getchar(); } } void ss() { for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if(a[i][j]==1) { p++; memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); memset(qian,0,sizeof(qian)); head=0; tail=1; qian[1]=0; x[1]=i; y[1]=j; a[i][j]=0; dis[p]++; while(head!=tail) { head++; for(int k=1;k<=4;k++) { int xx=x[head]+x0[k],yy=y[head]+y0[k]; if(a[xx][yy]==1) { tail++; x[tail]=xx; y[tail]=yy; qian[tail]=head; a[xx][yy]=0; dis[p]++; } } } } } void sss() { sort(dis+1,dis+p+1); int q=0; for(int i=2;i<=p;i++) q+=dis[i]; if(3*q>=k) { f=true; return; } } int main() { init(); ss(); // for(int i=1;i<=p;i++) printf("%d ",dis[i]); sss(); if(f==true) printf("Demacia Win!\\n"); else printf("Demacia Lose!\\n"); return 0; }
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● | ○ | ● | |
○ | ● | ○ | ● |
● | ○ | ● | ○ |
○ | ● | ○ |
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
用最少的步数移动到目标棋局的步数。
BWBO
WBWB
BWBW
WBWO
5
hi
#include <iostream> #include <algorithm> #include<cstdio> using namespace std; const int dx[4]={1,0,0,-1},dy[4]={0,1,-1,0}; int a[5][5],minn=10; void dfs(int x,int y,int num,int yes) { int m=10000; if(num>=minn) return; for(int i=1;i<=4;i++) { if (a[i][1]==a[i][2]&&a[i][2]==a[i][3]&&a[i][3]==a[i][4]&&(a[i][4]==1||a[i][4]==2)) m=num; if (a[1][i]==a[2][i]&&a[2][i]==a[3][i]&&a[3][i]==a[4][i]&&(a[4][i]==1||a[4][i]==2)) m=num; } if (a[1][1]==a[2][2]&&a[2][2]==a[3][3]&&a[3][3]==a[4][4]&&(a[4][4]==1||a[4][4]==2)) m=num; if (a[1][4]==a[2][3]&&a[2][3]==a[3][2]&&a[3][2]==a[4][1]&&(a[1][4]==1||a[1][4]==2)) m=num; if (m<minn) { minn=m; return; } for(int i=3;i>=0;i--) { int xx=x+dx[i],yy=dy[i]+y; if(xx>0&&xx<5&&yy>0&&yy<5&&yes==a[xx][yy]) { a[x][y]=a[xx][yy]; a[xx][yy]=0; if(yes==1) yes=2; else yes=1; for(int j=1;j<=4;j++) for(int k=1;k<=4;k++) if(!a[j][k]) dfs(j,k,num+1,yes); if(yes==1) yes=2; else yes=1; a[xx][yy]=a[x][y]; a[x][y]=0; } } } int main() { for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) { char tmp; cin>>tmp; if (tmp==\'W\') a[i][j]=2; else if (tmp==\'B\') a[i][j]=1; } for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(!a[i][j]) { dfs(i,j,0,1); dfs(i,j,0,2); } printf("%d",minn); return 0; }
计算乘法时,我们可以添加括号,来改变相乘的顺序,比如计算X1, X2, X3, X4, …, XN的积,可以
(X1(X2(X3(X4(...(XN-1*XN)...)))))
:::
:::
(((...(((X1*X2)X3)X4)...)XN-1)XN)
你的任务是编程求出所有这样的添括号的方案。
输入文件第一行是一个数n(1<=n<=10),表示有n个变量,之后N行每行一个变量的名字。
输出所有的添加括号的方案。注意:单个字符不要加括号,两个字符相乘中间要有乘号。
4
North
South
East
West
(North(South(East*West)))
(North((South*East)West))
((North*South)(East*West))
((North(South*East))West)
(((North*South)East)West)
#include <iostream> #include <string> #include <vector> using namespace std; vector<string> ans[12][12]; string str[11]; int n; void dfs(int l,int r) { if (ans[l][r].size()) { return; } if (l==r) { ans[l][l].push_back(str[l]); } else { for(int i=l;i<r;i++) { dfs(l,i); dfs(i+1,r); int sl=ans[l][i].size(), sr=ans[i+1][r].size(); for(int j=0;j<sl;j++) { for(int k=0;k<sr;k++) { string s; s="("+ans[l][i][j]; if(r-l==1) { s+="*"; } s+=(ans[i+1][r][k]+")"); ans[l][r].push_back(s); } } } } } int main(int argc, char** argv) { cin>>n; for(int i=1;i<=n;i++) { cin>>str[i]; } dfs(1,n); int m=ans[1][n].size(); for(int i=0;i<m;i++) { cout<<ans[1][n][i] << endl; } return 0; }
Abstinence(戒酒)岛的居民们酷爱一种无酒精啤酒。以前这种啤酒都是从波兰进口,但今年居民们想建一个自己的啤酒厂。岛上所有的城市都坐落在海边,并且由一条沿海岸线的环岛高速路连接。酒厂的投资者收集了关于啤酒需求量的信息,即每天各城市消费的啤酒桶数。另外还知道相邻城市之间的距离。每桶啤酒每英里的运费是1元。日运费是将所需要的啤酒从酒厂运到所有城市所必需的运费之和。日运费的多少和酒厂的选址有关。投资者想找到一个合适的城市来修建酒厂,以使得日运费最小。
请设计一个程序:从文件bre.in 读入城市的数目、相邻两城市间的距离以及每个城市消费的啤酒桶数,计算最小的日运费,将结果写到输出文件bre.out中。
第一行是一个整数n(5 <= n <= 10000) ,表示城市的数目。 城市沿高速路编号,使得相邻的城市的编号也相邻(城市1和n也被认为是相邻)。 以下的n行,每行有两个非负整数。第I+1行的数 zi、di分别是城市I每日的啤酒消费量(桶)和从城市I沿高速路到下一个城市的距离(英里)。高速路的总长不会超过65535 英里。每座城市的日消费量不会超过255桶。
一个整数,表示所需的最小日运费(元)。
6
1 2
2 3
1 2
5 2
1 10
2 3
41
#include<cstdio> #include<iostream> #define M 20010 #define INF 9223372036854775807LL using namespace std; int a[M],b[M],n; long long c[M]; int sum=0; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); for(int i=1;i<=n;i++) { a[i+n]=a[i]; b[i+n]=b[i]; } for(int i=1;i<=n;i++) sum+=b[i]; for(int i=1;i<=n;i++) { int t=0; for(int j=i-1+n;j>=i+1;j--) { t+=b[j]; c[i]+=min(t,sum-t)*a[j]; } } long long m=INF; for(int i=1;i<=n;i++) m=min(m,c[i]); cout<<m; return 0; }