山东省第一届acm程序设计竞赛题解

Posted 罚时自动机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了山东省第一届acm程序设计竞赛题解相关的知识,希望对你有一定的参考价值。

缺c 计算几何没看 f一个模拟,不想写,难度不大,J,因为时间挺早的,题目都比较简单,没什么难度,组队出个8题还是轻松的

A:水题

技术分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e3+5;
 4 string s[maxn];
 5 
 6 bool judge(string s1,string s2){
 7     if(s1.length()>s2.length())return 1;
 8     int len=s1.length();
 9     for(int i=0;i<len;i++)
10         if(s1[i]!=s2[i])
11             return true;
12     return false;
13 }
14 
15 int main(){
16     int n;
17     while(cin>>n,n){
18         bool ok=1;
19         for(int i=0;i<n;i++)cin>>s[i];
20         
21         for(int i=0;i<n;i++)
22             for(int j=i+1;j<n;j++)
23                 if(judge(s[i],s[j])&&judge(s[j],s[i]))
24                     continue;
25                 else {
26                     ok=0;break;
27                 }
28         
29         if(ok)puts("YES");
30         else puts("NO");
31         
32     }
33     return 0;
34 }
View Code

b:输出4联通和8联通的联通快数,水题

技术分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=105;
 4 const int dx[]={0,0,1,-1,-1,1,-1,1};
 5 const int dy[]={1,-1,0,0,1,1,-1,-1};
 6 char g[maxn][maxn];
 7 int v[maxn][maxn],n;
 8 
 9 inline bool judge(int x,int y){
10     if(x<0||x>=n||y<0||y>=n||g[x][y]==0)return true;
11     return false;
12 }
13 
14 void dfs(int x,int y,int t){
15     if(v[x][y])return ;
16     v[x][y]=1;
17     for(int i=0;i<t;i++){
18         int nx=x+dx[i];
19         int ny=y+dy[i];
20         if(judge(nx,ny))continue;
21         dfs(nx,ny,t);
22     }
23 }
24 
25 
26 int main(){
27     int cas=1;
28     while(~scanf("%d",&n),n){
29         for(int i=0;i<n;i++)scanf("%s",g[i]);
30         memset(v,0,sizeof(v));
31         
32         int res1=0,res2=0;
33         for(int i=0;i<n;i++)for(int j=0;j<n;j++){
34             if(g[i][j]==0)continue;
35             if(!v[i][j])res1++;
36             dfs(i,j,4);
37         }
38         memset(v,0,sizeof(v));
39         for(int i=0;i<n;i++)for(int j=0;j<n;j++){
40             if(g[i][j]==0)continue;
41             if(!v[i][j])res2++;
42             dfs(i,j,8);
43         }
44         printf("Case %d: %d %d\n",cas++,res1,res2);
45         puts("");
46     }
47     return 0;
48 }
View Code

d.排下序,水题

技术分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+5;
 5 int d[maxn];
 6 
 7 int main(){
 8     int n;
 9     while(cin>>n,n){
10         for(int i=0;i<n;i++)cin>>d[i];
11         sort(d,d+n);
12         ll res=d[n-1]-d[0];
13         
14         for(int i=1;i<n;i++)res+=d[i]-d[i-1];
15         cout<<res<<endl;
16     }
17     return 0;
18 }
View Code

E:n个城市都沦陷了,有两种操作0 x占领x,1 x y,输出x y的最短路

因为每个点只会被占领一次,只要用这个点来更新其他点就好

技术分享
 1 #include<iostream>
 2 #include<cmath>
 3 #include<string.h>
 4 #include<stdio.h>
 5 #define INT_MAX 100000
 6 using namespace std;
 7 int n,m,q;
 8 int map[310][310],vis[310];
 9 void floyd(int k){
10     int i,j;
11     for(i=0;i<n;i++)
12         for(j=0;j<n;j++)
13     {
14         if((map[i][k]!=INT_MAX) && (map[k][j]!=INT_MAX))
15         if(map[i][j]>map[i][k]+map[k][j])
16             map[i][j]=map[i][k]+map[k][j];
17     }
18 }
19 void init()
20 {
21     int i,j;
22     for(i=0;i<310;i++){
23         for(j=0;j<310;j++)
24             map[i][j]=INT_MAX;
25         map[i][i]=0;
26     }
27 }
28 int main()
29 {
30     int i,j,k,l,x,y,z,d,c=0;
31     while(cin>>n>>m>>q&&(n||m||q))
32     {
33         init();
34         memset(vis,0,sizeof(vis));
35         for(int i=0;i<m;i++){
36             cin>>x>>y>>z;
37             if(map[x][y]>z)
38                 map[x][y]=z;
39         }
40         printf("Case %d:\n",++c);
41         for(j=0;j<q;j++){
42             cin>>d;
43             if(!d){
44                 cin>>x;
45                 if(!vis[x]){
46                     vis[x]=1;
47                     floyd(x);
48                 }
49                 else printf("City %d is already recaptured.\n",x);
50             }
51             else{
52                 cin>>x>>y;
53                 if(!vis[x]||!vis[y])
54                     printf("City %d or %d is not available.\n",x,y);
55                 else if(map[x][y]==INT_MAX)
56                     cout<<"No such path."<<endl;
57                 else cout<<map[x][y]<<endl;
58             }
59         }
60         cout<<endl;
61     }
62     return 0;
63 }
View Code

F:模拟题,题意难读,不过好写,110行就差不多能写完

G:n个数,从中取四个数,每个数可以重复取,输出小于等于M的最大值

先把两个数和的存下来,排个序,然后双指针就Ok

技术分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e3+5;
 5 int d[maxn],c[maxn*maxn];
 6 int n,m;
 7 
 8 int main(){
 9     int cas=1;
10     while(cin>>n>>m,n){
11         for(int i=0;i<n;i++)cin>>d[i];
12         int cnt=0;
13         for(int i=0;i<n;i++)for(int j=0;j<n;j++)
14             c[cnt++]=d[i]+d[j];
15         
16         sort(c,c+cnt);
17         
18         int l=0,r=cnt-1;
19         ll res=0;
20         while(c[r]>m)r--;
21         
22         while(l<=r){
23             if((ll)c[l]+c[r]>m)r--;
24             else {
25                 res=max(res,(ll)c[l]+c[r]);
26                 l++;
27             }
28             if(res==m)break;
29         }
30         printf("Case %d: %lld\n\n",cas++,res);
31     }
32     return 0;
33 }
View Code

H:输出在(x,y)右边以及下面的第一个点,具体要求看题目

n只有300,直接爆

技术分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1005;
 4 int x[maxn],y[maxn],z[maxn];
 5 
 6 int main(){
 7     int n,cas=1;
 8     while(cin>>n,n){
 9         for(int i=0;i<n;i++)cin>>x[i]>>y[i],z[i];
10         
11         int nx,ny;
12         printf("Case %d:\n",cas++);
13         for(int i=0;i<n;i++){
14             nx=ny=-1;
15             for(int j=0;j<n;j++)
16                 if(x[j]>x[i]&&y[j]>y[i]){
17                     if(nx==-1)nx=x[j],ny=y[j];
18                     else if(x[j]<nx)nx=x[j],ny=y[j];
19                     else if(x[j]==nx&&y[j]<ny)ny=y[j];
20                 }
21             printf("%d %d\n",nx,ny);
22         }
23         puts("");
24     }
25     return 0;
26 }
View Code

I:上一题的加强版,可以加入一个点,删除一个点,然后查询一个点的右下方点,要求和上面一样

分析:讲道理写了个AVL插入两个元素应该没问题,迷之超时,set套pair,找到第然后二分找一下点,然后符合要求的肯定在后面,找到第一个点就好了

J:题目太长,没看

以上是关于山东省第一届acm程序设计竞赛题解的主要内容,如果未能解决你的问题,请参考以下文章

红书《题目与解读》第一章 数学 题解《ACM国际大学生程序设计竞赛题目与解读》

第十一届山东省大学生程序设计竞赛 L. Construction of 5G Base Stations(概率期望,递推前缀和优化)

数学 题解《ACM国际大学生程序设计竞赛题目与解读》

数学 题解《ACM国际大学生程序设计竞赛题目与解读》

“师创杯”山东理工大学第九届ACM程序设计竞赛

[2012山东省第三届ACM大学生程序设计竞赛]——Mine Number