• 山东省第一届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
    ",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:
    ",++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.
    ",x);
    50             }
    51             else{
    52                 cin>>x>>y;
    53                 if(!vis[x]||!vis[y])
    54                     printf("City %d or %d is not available.
    ",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
    
    ",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:
    ",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
    ",nx,ny);
    22         }
    23         puts("");
    24     }
    25     return 0;
    26 }
    View Code

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

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

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 set< pair<int,int> >st;
     5 set< pair<int,int> >::iterator it;
     6 
     7 int main(){
     8     int n;pair<int,int>p;
     9     int ca=1;
    10     while (~scanf("%d",&n)&&n){
    11         st.clear();
    12         printf("Case %d:
    ",ca++);
    13         for (int i=0;i<n;i++){
    14             char op[8];
    15             scanf("%s%d%d",op,&p.first,&p.second);
    16             if (op[0]=='a') st.insert(p);
    17             else if ((op[0]=='r')) st.erase(p);
    18             else{
    19                 it=st.upper_bound(p);
    20                 for(;it!=st.end();it++)
    21                     if(it->first>p.first&&it->second>p.second)
    22                         break;
    23                 if (it==st.end()) puts("-1");
    24                 else printf("%d %d
    ",it->first,it->second);
    25             }
    26         }
    27         puts("");
    28     }
    29 }
    View Code

    J:题目太长,没看

  • 相关阅读:
    ACM学习历程——POJ3321 Apple Tree(搜索,线段树)
    ACM学习历程——NOJ1113 Game I(贪心 || 线段树)
    ACM学习历程——HDU5202 Rikka with string(dfs,回文字符串)
    ACM学习历程——hihoCoder挑战赛10A 01串(策略)
    ACM学习历程——POJ3468 A Simple Problem with Integers(线段树)
    ACM学习历程——POJ1260 Pearls(动态规划)
    java入门了解09
    java入门了解08
    java入门了解之快捷键
    java入门了解07
  • 原文地址:https://www.cnblogs.com/jihe/p/6657212.html
Copyright © 2020-2023  润新知