SHU 第十届程序设计联赛(夏季赛) 解题报告

Problem A: 一日三餐开销

水题,基本上都过了,直接贴代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 int main()
 5 {
 6     double a,b,c;
 7     while(cin>>a>>b>>c)
 8     {
 9         printf("%.1f\n",a+b+c);
10     }
11 }
View Code

 

Problem B: 一道简单的题

简单排序,只要从小到大排序输出就可以了,注意数组最后没有空格。

#include <iostream>
#include <cstdio>
#include<algorithm>
using namespace std;
int t,a[1100],n;
int main ()
{
    scanf("%d",&t);
    while(t--)
    {
        cin>>n;
        for(int i=0;i<n;++i)
            cin>>a[i];
        sort(a,a+n);
        cout<<a[0];
        for(int i=1;i<n;++i)
            cout<<" "<<a[i];
        cout<<endl;
    }
}
View Code

Problem C: 转置矩阵

水题,直接输出转置矩阵即可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int a[10][10];
 6 int main ()
 7 {
 8     for(int i=0;i<3;++i)
 9     {
10         for(int j=0;j<3;++j)
11             cin>>a[i][j];
12     }
13     for(int i=0;i<3;++i)
14     {
15         cout<<a[0][i];
16         for(int j=1;j<3;++j)
17         {
18             cout<<" "<<a[j][i];
19         }
20         cout<<endl;
21     }
22 }
View Code

Problem D: 母猪生崽

递推,根据题意可以推出递推式为a[i]=a[i-1]+a[i-3]

 1 #include <iostream>
 2 #include <cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 long long a[60]= {1,1,2,3,4};
 6 int main()
 7 {
 8     int n;
 9     for(int i=4; i<58; ++i)
10         a[i]=a[i-1]+a[i-3];
11     while(cin>>n)
12     {
13         if(n==0)
14             break;
15         printf("%lld\n",a[n]);
16     }
17 }
View Code

Problem E: 买书问题

跟那道百元买白鸡的题目很像,这里只给出很水很暴力的枚举

 1 #include <iostream>
 2 #include <cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int main ()
 6 {
 7     int n;
 8     while(cin>>n)
 9     {
10         int ans=0;
11         for(int i=0;i<=n/100;++i)
12         {
13             for(int j=0;j<=n/50;++j)
14             {
15                 for(int k=0;k<=n/20;++k)
16                 {
17                     for(int l=0;l<=n/10;++l)
18                     {
19                         if(100*i+50*j+20*k+10*l==n)
20                             ans++;
21                     }
22                 }
23             }
24         }
25         printf("%d\n",ans);
26     }
27 }
View Code

Problem F: 琪露诺的算数考试

字符串处理+简单判断

 1 #include <iostream>
 2 #include <cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int main ()
 6 {
 7     int t,n,a,b,c,ans;
 8     char ch,ch2;
 9     cin>>t;
10     while(t--)
11     {
12         cin>>n;
13         ans=0;
14         for(int i=0;i<n;++i)
15         {
16             cin>>a>>ch>>b>>ch2>>c;
17             if(ch=='+'&&a+b==c)
18                 ans++;
19             else if(ch=='-'&&a-b==c)
20             ans++;
21         }
22         cout<<ans<<"/"<<n<<endl;
23     }
24 }
View Code

Problem G: 悟空的难题

题目意思就是有n个点,每个点上面有能量f[i],所在位置为k[i],你所在的位置将受到这个点f[i]-s(如果小于零当零处理)的伤害,

s表示你的位置与这个点的距离。你所在的位置是0-L之间的任意整数。现在要求你在那个位置上受到的伤害之和最小。

分析:

我们可以枚举0-l之间的每一位置,求一下在这位置受到伤害之和,然后求一下最小值,并计入位置就可以了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include<algorithm>
 4 #include <cstring>
 5 #define INF 0x7ffff
 6 using namespace std;
 7 int t,n,l,f[2010],dist[2010];
 8 int main ()
 9 {
10     scanf("%d",&t);
11     while(t--)
12     {
13         scanf("%d%d",&l,&n);
14         for(int i=0;i<n;++i)
15             scanf("%d",&dist[i]);
16         for(int i=0;i<n;++i)
17             scanf("%d",&f[i]);
18         int ans=INF,index=0;
19         for(int i=0;i<=l;++i)
20         {
21             int temp=0;
22             for(int j=0;j<n;++j)
23             {
24                 if(f[j]-abs(dist[j]-i)>0)
25                 temp+=f[j]-abs(dist[j]-i);
26             }
27             if(ans>temp)
28             {
29                 index=i,ans=temp;
30             }
31         }
32         printf("%d %d\n",index,ans);
33     }
34 }
View Code

Problem H: 拯救宇宙

Description

有这么一个传说,如果你在Google的主页搜索"Google",那么宇宙将会爆炸。请不要尝试这么做,或者告诉其他任何人。好吧,也许不是这样,仅仅是开个玩笑。

对于很远很远的一个宇宙来说,这个就是真的。在那个宇宙中,如果你在任何搜索引擎中搜索该引擎的名字,那么这个宇宙就会爆炸。

为了防止这种情况,人们提出了一个有趣的解决办法。把所有的查询集中起来并把他们传递给一个可以决定什么查询发送给什么搜索引擎的中心系统。这个中心系统发送一连串的查询给一个搜索引擎,并且可以在任何时候切换给另一个搜索引擎。查询必须按照他们被接收的顺序来处理。这个中心系统一定不能发送一个查询给和该查询同名的搜索引擎。为了节约成本,切换的次数应该最少。

你的任务是告诉我们,假设我们编写最优的程序那么中心系统将必须切换搜索引擎多少次。

Input

输入文件的第一行包括了总组数N,也就是说一共有N组数据。

每组数据以数字S(搜索引擎的总数)开头。在接下来的S行中,每一行包括了一个搜索引擎的名字。每一个引擎的名字都不会超过100个字符的长度,并且只含有大写字母、小写字母、空格和数字,也不会有两个搜索引擎拥有相同的名字。

接下来的一行包括了数字Q——接收到的查询的数目。之后的Q行都包含一个查询。每一个查询都将是该组其中一个搜索引擎的名字。

其中0 < N ≤ 20, 2 ≤ S ≤ 100, 0 ≤ Q ≤ 1000

Output

对于每一组输入,你将(按如下格式)输出:Case #X: Y

其中X是当前组的标号,Y是搜索引擎的切换次数。不要把初始选择一个搜索引擎也当作切换来计数。

首先这道题目的输入需要小心处理一下,算法的话我的程序觉得属于贪心,由于查询时按一定顺序的,所以开一个visited数组记录一下这个搜索引擎是否被询问过,询问过就标记。

那么对于每一次询问,如果之前这n个搜索引擎没有都出现过,就说明可以选择那个没有出现过的引擎来达到变换次数最少,当n个搜索引擎都出现了,那么就需要变换次数+1并将

visited清零(未出现),同时需要注意的是将上一个询问再次询问,(例如前k次visited数组存在0,k+1次询问时visited不存在0,这说明前k次我们可以选择第k+1这个名字的搜索引擎来搜索前k个询问)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include<algorithm>
 4 #include <cstring>
 5 #include <map>
 6 #define INF 0x7ffff
 7 using namespace std;
 8 int t,n,q;
 9 char names[1010][300],que[1010][300];
10 int  visited[1010];
11 int main()
12 {
13     scanf("%d",&t);
14     for(int Case=1; Case<=t; ++Case)
15     {
16         cin>>n;
17         gets(names[0]);
18         memset(names,0,sizeof(names));
19         for(int i=0; i<n; ++i)
20         {
21             gets(names[i]);
22         }
23         memset(visited,0,sizeof(visited));
24         cin>>q;
25         gets(que[0]);
26         int ans=0;
27         memset(que,0,sizeof(que));
28         for(int i=0; i<q; ++i)
29         {
30             gets(que[i]);
31         }
32         for(int i=0; i<q; ++i)
33         {
34             for(int j=0; j<n; ++j)
35             {
36                 if(strcmp(que[i],names[j])==0)
37                 {
38                     visited[j]++;
39                 }
40             }
41             int cnt=0;
42             for(int i=0; i<n; ++i)
43             {
44                 if(visited[i]!=0)
45                     cnt++;
46             }
47             if(cnt==n)
48             {
49                 memset(visited,0,sizeof(visited));
50                 --i;
51                 ans++;
52             }
53         }
54         printf("Case #%d: %d\n",Case,ans);
55     }
56 }
View Code

另一种解法,动态规划by 丁小贤

 1 //problem hhhhhhhhhhhh
 2 #include<iostream>
 3 #include<stdio.h>
 4 #include<string.h>
 5 #include<algorithm>
 6 using namespace std;
 7 char a[1010][1010];
 8 int que[1010];
 9 int dp[1010][1010];
10 int n,s,q;
11 int ffind(char *p)
12 {
13     for(int i=0; i<s; i++)
14         if(strcmp(p,a[i])==0)return i;
15     return 0;
16 }
17 int main()
18 {
19     cin>>n;
20     for(int cnt=1; cnt<=n; cnt++)
21     {
22         memset(dp,0,sizeof(dp));
23         cin>>s;//cout<<s<<endl;
24         gets(a[0]);
25        //cin.getline(a[1110],111,'\r');
26         for(int i=0; i<s; i++)
27         {
28             gets(a[i]);
29            // cin.getline(a[i],111,'\r');//cout<<a[i]<<"***"<<endl;
30         }
31         cin>>q;
32         gets(a[1008]);
33        //cin.getline(a[1110],111,'\r');
34         char x[1111];
35         for(int i=0; i<q; i++)
36         {
37             gets(x);
38             //cin.getline(x,111,'\r');
39             que[i]=ffind(x);//cout<<que[i]<<endl;
40         }
41         dp[0][que[0]]=-1;
42         for(int i=1; i<q; i++)
43         {
44             int mm=9999;
45             for(int j=0; j<s; j++)if(dp[i-1][j]<mm&&dp[i-1][j]>=0)mm=dp[i-1][j];
46             //cout<<mm<<endl;
47             for(int j=0; j<s; j++)
48             {
49                 if(j==que[i])
50                     dp[i][j]=-1;
51                 else
52                 {
53                     if(dp[i-1][j]==mm)
54                     {
55                         dp[i][j]=mm;
56                     }
57                     else
58                         dp[i][j]=mm+1;
59                 }//cout<<dp[i][j]<<' ';
60             }//cout<<endl;
61         }
62         if(q==0){cout<<"Case #"<<cnt<<": 0"<<endl;continue;}
63         int ans=9999;
64         for(int j=0; j<s; j++)if(dp[q-1][j]<ans&&dp[q-1][j]>=0)ans=dp[q-1][j];
65         cout<<"Case #"<<cnt<<": "<<ans<<endl;
66     }
67     return 0;
68 }
View Code

Problem I: 与生命赛跑

Description

小张是SH市急救中心的一名工作人员,他的工作就是:每天可能接到救助任务,要将一部救护车从A处开往B处,小张需要为急救车制定一条从A至B的交通路线。小张一次只能处理一项救助任务,等到当前的救助任务完成了,才能处理下一项。

不过,现在科技发达了,急救车可以不用在普通道路上行驶。市政府在每一条道路上设立了紧急通道,平时这些通道是隐藏起来的,在需要使用时,信息化控制中心可以启动某些通道,并将这些通道连接成高速轨道,供急救车、消防车等紧急车辆通行。车辆在高速通道中可以达到接近光速的移动速度,只需设定终点,就能立即传送到目的地。

在处理每项救助任务前,路径上的紧急通道启动都要进行一系列的准备操作,如轨道连接、车辆改道等等。小张在急救中心一声令下,这些通道的准备操作同时开始,但由于各条通道的长度、路况不同,进行准备操作需要的时间可能不同,当路径上所有道路的紧急通道启动完毕后,救护车方能通行。对于急救来说,时间就是生命,所以急救中心总是希望小张能找到一条准备时间最短的路径。小张希望你能帮助他完成这样的一个选择路径的系统。另外,由于SH市的交通情况复杂多变,一些道路会不时出现交通事故、道路施工、严重交通阻塞等情况导致紧急通道无法启动,你的程序必须考虑到这一点。

不妨将SH市的交通网络看作一幅简单无向图(即没有自环或重边):道路是图中的边,道路的连接处为图中的结点。

Input

输入的第一行为3个整数:N, M, Q分别表示道路连接处(结点)的数目、目前道路(无向边)的数目,以及你的程序需要处理的任务数目(包括寻找一条满足要求的路径和接受某条道路无法通行的事实)。

以下M行,每行3个整数x, y和t,描述一条对应的道路。x和y表示道路两端结点的编号,t表示这条道路的紧急通道启动所需的准备时间。我们不妨为结点从1至N编号,这样所有的x和y都在范围[1, N]内。

以下Q行,每行描述一项任务。其中第一个整数为k:若k=1则后跟两个整数A和B,表示你需要寻找一条满足要求的从A到B的路径;若k=2,则后跟两个整数x和y,表示直接连接x和y的道路的紧急通道无法启动(保证合法,即在此之前直接连接x和y的道路一定存在)。

其中N ≤ 1000, M ≤ 100000, Q ≤ 100000

测试数据中无法启动的紧急通道不超过5000条;且任何时候我们考虑的交通网络都是连通的,即从任一结点A必有至少一条路径通往任一结点B。

Output

按顺序对应输入数据中每一项k=1的任务,你需要在一行内输出一个数字。该数字表示:你寻找到的路径紧急通道启动所需要的时间(当然要求最短)。

Sample Input

4 4 3
1 2 2
2 3 3
3 4 2
1 4 2
1 1 4
2 1 4
1 1 4

Sample Output

2
3

写不来,以后填坑。呼叫学长解题报告。原题为水管局长,请先自行百度研究。

转载于:https://www.cnblogs.com/shuzy/p/3180938.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值