ACM河南第八届省赛题

来源:互联网 发布:php环境集成包 编辑:程序博客网 时间:2024/04/27 17:13

挑战密室

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

R组织的特工Dr.Kong 为了寻找丢失的超体元素,不幸陷入WTO密室。Dr.Kong必须尽快找到解锁密码逃离,否则几分钟之后,WTO密室即将爆炸。

 

Dr. Kong发现密室的墙上写了许多化学方程式中。化学方程式,也称为化学反应方程式,是用化学式表示物质化学反应的式子。化学方程式反映的是客观事实。因此书写化学方程式要遵守两个原则:一是必须以客观事实为基础;二是要遵守质量守恒定律。

化学方程式不仅表明了反应物、生成物和反应条件。同时,化学计量数代表了各反应物、生成物物质的量关系,通过相对分子质量或相对原子质量还可以表示各物质之间的质量关系,即各物质之间的质量比。对于气体反应物、生成物,还可以直接通过化学计量数得出体积比。例如:2NaOH+H2SO4=Na2SO4+2H2O

 

经过多次试探、推理,Dr. Kong发现密码是4位数字,就隐藏在化学方程式等号后的第一个分子中,其分子量就可能是密码(若分子量不足4位,前面加0)。

好在Dr.Kong还记得墙上各化学方程式用到的化学元素的原子量如下:

 

N

C

O

Cl

S

H

Al

Ca

Zn

Na

14

12

16

35

32

2

27

40

65

23

 

你能帮Dr. Kong尽快找到密码吗?

输入
第一行: K,表示有K个化学方程式;
接下来有K行,每行为一个化学方程式
输出
对于每个化学方程式输出一行:即密码。
样例输入
32C+O2=2CO2NaOH+H2SO4=Na2SO4+2H2OCa2CO3+H2O=Ca2(OH)2+CO2
样例输出
005601420116
提示
2≤K≤8 ,化学方程式的长度不超过50, 所有原子,分子的数量不超过9.小括号最多一层.
<span style="font-family:SimSun;font-size:18px;"> #include <stdio.h>#include <string.h>#include <stack>using namespace std;char letter[12][5] = {"N","C","O","Cl","S","H","Al","Ca","Zn","Na"};int figure[12] = {14,12,16,35,32,2,27,40,65,23};char s[55];struct Node{char ch[5];}N;int num,ans,res;stack<Node> S;int solve(char *c){int i;for(i=0;i<10;i++){if(strcmp(c,letter[i])==0){return figure[i];}}}int find(int i){int sum = 0;if(s[i]>='A' && s[i]<='Z' && s[i+1]>='a' && s[i+1]<='z'){N.ch[0] = s[i];N.ch[1] = s[i+1];N.ch[2] = '\0';S.push(N);}else if(s[i]>='A' && s[i]<='Z'){N.ch[0] = s[i];N.ch[1] = '\0';S.push(N);}else if(s[i]>'1' && s[i]<='9'){Node p = S.top();sum += solve(p.ch) * (s[i]-'0');S.pop();}return sum;}int main(){int T;scanf("%d",&T);while(T--){getchar();int i=0,j;ans = 0, res = 0 ,num = 1;scanf("%s",s);int len = strlen(s);while(s[i++]!='=');if(s[i]>'1' && s[i]<='9'){num = s[i++] - '0';}while(s[i]!='+' && i<len){ans += find(i);i++;if(s[i] == '('){N.ch[0] = '(';N.ch[1] = '\0';S.push(N);while(s[i]!=')'){res += find(i);i++;}Node p = S.top();S.pop();while(strcmp(p.ch,"(")!=0){res += solve(p.ch);p = S.top();S.pop();}if(s[++i]>'1' && s[i]<='9'){res *= (s[i++] - '0');}}}while(!S.empty()){Node p = S.top();ans += solve(p.ch);S.pop();}int res_s = num * (ans + res);if(res_s<10){printf("000%d\n",res_s);}else if(res_s<100){printf("00%d\n",res_s);}else if(res_s<1000){printf("0%d\n",res_s);}else{printf("%d\n",res_s);}}return 0;}        </span>

最大岛屿

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
描述

神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等。加勒比海盗,你知道吧?杰克船长驾驶着自己的的战船黑珍珠1号要征服各个海岛的海盜,最后成为海盗王。  这是一个由海洋、岛屿和海盗组成的危险世界。面对危险重重的海洋与诡谲的对手,如何凭借智慧与运气,建立起一个强大的海盗帝国。

杰克船长手头有一张整个海域的海图,上面密密麻麻分布着各个海屿的位置及面积。他想尽快知道整个海域共有多少岛屿以及最大岛屿的面积。

输入
第1行:M N T,表示海域的长,宽及一个单位表示的面积大小
接下来有M行 ,每行有N个01组成的序列以及其中穿插一些空格。0表示海水,1表示陆地,其中的空格没用,可以忽略掉。

输出
输出一行,有2个整数,一个空格间隔,表示整个海域的岛屿数,以及最大岛屿的面积
样例输入
8 16 9900000000 00000000000011001100000000011110001110000000000  00 000000000111  111000001  10001110000  00000000100001111 1111000000000000000000

样例输出
5 990
#include <stdio.h>#include <string.h>int g[502][502];int m,n,t;char map[1005];int ans;void DFS(int x,int y){if(!g[x][y]){return ;}ans++;g[x][y] = 0;DFS(x,y+1);DFS(x,y-1);DFS(x-1,y);DFS(x+1,y);DFS(x+1,y+1);DFS(x+1,y-1);DFS(x-1,y+1);DFS(x-1,y-1);}int main(){while(scanf("%d%d%d",&m,&n,&t)!=EOF){getchar();memset(g,0,sizeof(g));int i,j,k;int len;for(i=1;i<=m;i++){gets(map);len = strlen(map);for(j=0,k=1;j<len;j++){if(map[j]!=' '){g[i][k++] = map[j]-'0';}}}int sum=0;int max=-0x3f3f3f;for(i=1;i<=m;i++){for(j=1;j<=n;j++){if(g[i][j]==1){sum++;  ans = 0;DFS(i,j);if(ans>max){max = ans;}}}}printf("%d %d\n",sum,max*t);}return 0;}

引水工程

时间限制:2000 ms  |  内存限制:65535 KB
难度:3
描述

南水北调工程是优化水资源配置、促进区域协调发展的基础性工程,是新中国成立以来投资额最大、涉及面最广的战略性工程,事关中华民族长远发展。“南水北调工程”,旨在缓解中国华北和西北地区水资源短缺的国家战略性工程。就是把中国长江流域丰盈的水资源抽调一部分送到华北和西北地区。我国南涝北旱,南水北调工程通过跨流域的水资源合理配置,促进南北方经济、社会与人口、资源、环境的协调发展。

整个工程分东线、中线、西线三条调水线。东线工程位于东部,因地势低需抽水北送至华北地区。中线工程从汉水与其最大支流丹江交汇处的丹江口水库引水,自流供水给黄淮海平原大部分地区,20多座大中城市;西线工程在青藏高原上,由长江上游向黄河上游补水。

现在有N个区域需要建设水资源工程,它们可以自建水库解决缺水问题,也可以从已有水源的地区建立管道引水过来。当然,这些建设都需要大量投资。

你能不能给出一个优化水资源配置方案,在保证每个区域都能用上水的前提下,使得整个引水工程费用最低。

输入
第一行: K 表示有多少组测试数据。
接下来对每组测试数据:
第1行: N 表示有N个区域( 1<=N<=300 )
第2 行: W1 W2 …. WN Wi表示第i个区域自建水库需要的费用
再有N行: Pi1 Pi2 …. Pin Pij表示建立第i个区域与第j个区域引水管道的费用
输出
对于每组测试数据,输出占一行,即建立整个引水工程的最小费用。
样例输入
155 4 4 3 60 2 2 2 22 0 3 3 32 3 0 4 52 3 4 0 12 3 5 1 0
样例输出
10
#include <stdio.h>#include <string.h>#define inf 0x3f3f3f3f#define Max_N 310int g[Max_N][Max_N];int vis[Max_N];int cost[Max_N];int n;int Prim(){memset(vis,0,sizeof(vis));int sum=0;while(1){int u=-1,i,min=inf,v;for(i=1;i<=n;i++){if(!vis[i] && min>cost[i]){min = cost[i];u = i;}}vis[u]=1;if(u==-1){break;}sum += cost[u];for(v=1;v<=n;v++){if(!vis[v] && g[u][v]!=inf && cost[v]>g[u][v]){cost[v] = g[u][v];}}}return sum;}int main(){int t;scanf("%d",&t);while(t--){scanf("%d",&n);int i,j,k;memset(cost,inf,sizeof(cost));for(i=1;i<=n;i++){scanf("%d",&cost[i]);}memset(g,inf,sizeof(g));for(i=1;i<=n;i++){for(j=1;j<=n;j++){scanf("%d",&g[i][j]);}}printf("%d\n",Prim());}        return 0;}        

最少换乘

时间限制:2000 ms  |  内存限制:65535 KB
难度:3
描述

 欧洲某城是一个著名的旅游胜地,每年都有成千上万的人前来观光旅行。Dr. Kong决定利用暑假好好游览一番。。

年轻人旅游不怕辛苦,不怕劳累,只要费用低就行。但Dr. Kong年过半百,他希望乘坐BUS从住的宾馆到想去游览的景点,期间尽可量地少换乘车。

 

Dr. Kon买了一张旅游地图。他发现,市政部门为了方便游客,在各个旅游景点及宾馆,饭店等地方都设置了一些公交站并开通了一些单程线路。每条单程线路从某个公交站出发,依次途经若干个站,最终到达终点站。

但遗憾的是,从他住的宾馆所在站出发,有的景点可以直达,有的景点不能直达,则他可能要先乘某路BUS坐上几站,再下来换乘同一站的另一路BUS, 这样须经过几次换乘后才能到达要去的景点。

 

为了方便,假设对该城的所有公交站用1,2,……,N编号。Dr. Kong所在位置的编号为1,他将要去的景点编号为N。

请你帮助Dr. Kong寻找一个最优乘车方案,从住处到景点,中间换车的次数最少。

输入
第一行: K 表示有多少组测试数据。(2≤k≤8)
接下来对每组测试数据:
第1行: M N 表示有M条单程公交线路,共有N站。(1<=M<=100 1<N<=500)
第2~M+1行: 每行描述一路公交线路信息,从左至右按运行顺序依次给出了该线路上的所有站号,相邻两个站号之间用一个空格隔开。
输出

对于每组测试数据,输出一行,如果无法乘坐任何线路从住处到达景点,则输出"N0",否则输出最少换车次数,输出0表示不需换车可以直达。


存储思路:只要在一条路线上,起点到终点距离都是1, 例如:6->7=1,

                                                                                                            4->7=1, 4->3=1, 4->1 = 1,7->3=1, 7->1 = 1, 3->=1;

                                                                                                             ..........


23 76 74 7 3 62 1 3 52 61 3 5 2 6 4 3
样例输出
2NO 

<pre name="code" class="plain">#include <stdio.h>#include <string.h>using namespace std;#define inf 0x3f3f3f3fint m,n,i,j,l;int map[502][502];char s[1020];int x[502];int dist[502];bool used[502];void init(){memset(dist,inf,sizeof(dist));memset(used,false,sizeof(used));}void Dijkstra(int begin){init();for(int i=1;i<=n;i++){dist[i] = map[1][i];}used[begin] = true;while(1){int min = inf,u=-1,v;for(i=1;i<=n;i++){if(min>dist[i] && !used[i]){min = dist[i];u = i;}}used[u] = true;if(u==-1){break;}for(v=1;v<=n;v++){if(map[u][v]!=inf && dist[v]>dist[u]+map[u][v]){dist[v] = dist[u] + map[u][v];}}}}int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d",&m,&n);getchar();memset(map,inf,sizeof(map));for(i=0;i<m;i++){int k = 0,sum;gets(s);for(j=0;j<strlen(s);j++){if(s[j]!=' '){sum = 0;while(s[j]!=' ' && j<strlen(s)){sum = sum * 10 + s[j] - '0';j++;}x[k++] = sum;}}for(j=0;j<k;j++){for(l=j+1;l<k;l++){map[x[j]][x[l]] = 1;}}}Dijkstra(1);if(dist[n]!=inf){printf("%d\n",dist[n]-1);}else{printf("NO\n");}}return 0;}

Distribution

时间限制:1000 ms  |  内存限制:65535 KB
描述

One day , Wang and Dong in the Dubai desertexpedition, discovered an ancient castle. Fortunately, they found a map of thecastle.The map marks the location of treasures.

They agreed to distribute the treasures according to the following rules:



Wang draws a horizontal line on the map and then Dong draws a vertical one so that the map is divided into 4 parts, as show below. 

Wang will save the treasures in I and III ,while thosesituated in II and IV will betaken away by Dong.Wangfirst draw a horizontal line, Dong after the draw a vertical line.

They drewseveral pairs of  lines. For each pair, Wangwants to know the difference between their treasures.

It's guaranteed that all the reasures will lie on neither of the linesdrew by them.

输入
the first line contains two integers N and M, where N is the number of treasures on the map and M indicates how many times they are going to draw the lines. The 2nd to (N+1)-th lines Xi, Yi contain the co-ordinates of the treasures and the last M lines consist of the M pairs integers (X, Y) which means that the two splitting lines intersect at point (X, Y).
( 0 < N, M ≤ 100, 0 ≤ Xi, Yi, X,Y ≤ 1000 )
输出
Output contains M lines , a single line with a integer , the difference described above
样例输入
10 3 29 2217 14 18 233 156 2830 274 126 78 011 212 255 1019 24
样例输出
-644
#include <stdio.h>struct Node{int a;int b;}s[105];int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){int i,j,x,y;for(i=0;i<n;i++){scanf("%d%d",&s[i].a,&s[i].b);}int sum1,sum2;for(i=0;i<m;i++){sum1 = 0;   sum2 = 0;scanf("%d%d",&x,&y);for(j=0;j<n;j++){if((s[j].a>x && s[j].b>y) || (s[j].a<x && s[j].b<y)){sum1++;}if((s[j].a>x && s[j].b<y) || (s[j].a<x && s[j].b>y)){sum2++;}}printf("%d\n",sum1-sum2);}}return 0;}        

Interference Signal

时间限制:2000 ms  |  内存限制:65535 KB
难度:1
描述

Dr.Kong’s laboratory monitorsome interference signals. The interference signals can be digitized into aseries of positive integer. May be, there are N integers a1,a2,…,an.

 

Dr.Kong wants toknow theaveragestrength ofa contiguous interference signal block.the block mustcontain at least M integers.

 

Pleasehelp Dr.Kong tocalculate the maximumaverage strength, giventhe constraint.

输入
The input contains K test cases. Each test case specifies:
* Line 1: Two space-separated integers, N and M.
* Lines2~line N+1: ai (i=1,2,…,N)
1 ≤ K≤ 8, 5 ≤ N≤ 2000, 1 ≤ M ≤ N, 0 ≤ ai ≤9999
输出
For each test case generate a single line containing a single integer that is 1000 times the maximal average value. Do not perform rounding.
样例输入
2 10 66 42103859415 210385 9
样例输出
6500
7333
 #include <stdio.h> #define Max_N 2001 int s[Max_N]; int Max(double a,double b) { return a>b?a:b; } int main() { int T; scanf("%d",&T); while(T--) { int m,n,g; scanf("%d%d",&n,&m); int i,j; s[0] = 0; for(i=1;i<=n;i++) { scanf("%d",&g); s[i] = s[i-1] + g;  } double sum = -0x3f3f3f3f,max; for(i=0;i<n;i++) { for(j=i+m;j<=n;j++) { max = (s[j]-s[i])*1.0/(j-i)*1000; sum = Max(max,sum); } } printf("%d\n",(int)sum); } return 0; }   


0 0
原创粉丝点击