2018.11.4薛猫杯比赛

题目链接:http://acm.hdu.edu.cn/diy/contest_show.php?cid=34362

 

题目比较水(有难度的1003,1007,1008)

 

1001,模拟,理解题意,排序找就行。0的话特殊考虑也是麻烦的一种,不为0就简单了,一个循环找下去记录就行。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 using namespace std;
 7 typedef long long ll;
 8 const int maxn=1e6+5;
 9 ll a[maxn];
10 ll t[maxn];
11 ll n;
12 
13 ll getcner(ll n)
14 {
15     n=n-1;
16     ll s=n*(1+n)/2;
17 
18     return s;
19 }
20 
21 int main()
22 {
23     ios::sync_with_stdio(false); cin.tie(0);
24 
25     int T;
26     cin>>T;
27     while(T--)
28     {
29         memset(t,0,sizeof(t));
30 
31         cin>>n;
32         for(int i=1;i<=n;i++) cin>>a[i];
33 
34         sort(a+1,a+1+n);
35         ll Min=1e9+5;
36         for(int i=2;i<=n;i++)
37         {
38             Min=min(Min,a[i]-a[i-1]);
39         }
40         if(Min==0)
41         {
42             ll last=a[1];
43             int p=1;
44             for(int i=2;i<=n;i++)
45             {
46                 if(a[i]==last) t[p]++;
47                 else
48                 {
49                     last=a[i];
50                     p++;
51                 }
52             }
53 
54             ll cnt=0;
55             for(int i=1;i<=p-1;i++)
56             {
57                 cnt+=getcner(t[i]+1);
58             }
59             if(t[p]) cnt+=getcner(t[p]+1);
60 
61             cout<<Min<<' '<<cnt<<endl;
62         }
63         else
64         {
65             ll cnt=0;
66             for(int i=2;i<=n;i++)
67             {
68                 if(a[i]-a[i-1]==Min) cnt++;
69             }
70 
71             cout<<Min<<' '<<cnt<<endl;
72         }
73     }
74 
75     return 0;
76 }

 

1002,简单题,模拟即可。用map和string会好做些。

 1 #include <iostream>
 2 #include <string>
 3 #include <map>
 4 using namespace std;
 5 map<int,string> mp;
 6 string s[53];
 7 
 8 int main()
 9 {
10 
11     int p=0;
12     char c=64;
13     for(int i=1;i<=4;i++)
14     {
15         c++;
16         for(int j=1;j<=13;j++)
17         {
18             if(j<=9)
19             {
20                 char t=j+'0';
21 
22                 string z="";
23                 z=z+c;
24                 z=z+t;
25 
26                 mp[++p]=z;
27             }
28             else
29             {
30                 string t;
31                 if(j==10) t="10";
32                 else if(j==11) t="J";
33                 else if(j==12) t="Q";
34                 else if(j==13) t="K";
35 
36                 string z="";
37                 z=z+c;
38                 z=z+t;
39 
40                 mp[++p]=z;
41             }
42         }
43     }
44 
45 
46     int T;
47     cin>>T;
48     while(T--)
49     {
50         for(int i=1;i<=51;i++) cin>>s[i];
51 
52         int f=0;
53         for(int i=1;i<=51;i++)
54         {
55             if(mp[i]!=s[i])
56             {
57                 f=i;
58                 break;
59             }
60         }
61         if(f==0) cout<<mp[52]<<endl;
62         else cout<<mp[f]<<endl;
63     }
64 }

 

1003,重点,经典二分题最小值最大化,Judge函数略难写,想了好长时间用2个数组写出Judge函数。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 using namespace std;
 7 typedef long long ll;
 8 const int maxn=1e6+5;
 9 ll a[maxn],t[maxn];
10 int L,N,M;
11 
12 ll judge(ll x)
13 {
14     for(int i=1;i<=N;i++) t[i]=a[i];
15     ll last=t[1],cnt=0;
16     for(int i=1;i<=N-1;i++)
17     {
18         if(t[i]<x)
19         {
20             cnt++;
21             t[i]+=t[i+1];
22             t[i+1]=t[i];
23         }
24         //else
25     }
26     if(t[N]<x) cnt++;
27 
28     return cnt;
29 }
30 
31 int main()
32 {
33     ios::sync_with_stdio(false); cin.tie(0);
34 
35     int t;
36     cin>>t;
37     while(t--)
38     {
39         cin>>N>>M;
40         ll l=1e7,sum=0;
41         for(int i=1;i<=N;i++) { cin>>a[i]; sum+=a[i]; l=min(l,a[i]); }
42 
43         //sort(a+1,a+1+N);
44         ll r=sum;
45         ll ans=0;
46         while(l<=r)
47         {
48             ll mid=(l+r)/2;
49 
50             int t=judge(mid);
51             if(t<=M)
52             {
53                 ans=max(ans,mid);
54                 l=mid+1;
55             }
56             else r=mid-1;
57         }
58 
59         cout<<ans<<endl;
60     }
61 
62     return 0;
63 }

 

1004,找为k的子矩阵,循环或递归找判断下去即可

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 using namespace std;
 8 typedef long long llo;
 9 const int maxn=1000;
10 int a[maxn][maxn];
11 int n,m,kk;
12 int f;
13 
14 void so(int x,int y,int k)
15 {
16     if(f) return;
17     if(k<0) return;
18 
19     for(int j=y;j<=y+k;j++) if(a[x][j]!=0) { f=1; return; }
20     for(int i=x;i<=x+k;i++) if(a[i][y]!=0) { f=1; return; }
21 
22     if(f==0 && x+1<=n && y+1<=m) so(x+1,y+1,k-1);
23 
24 }
25 
26 int main()
27 {
28     ios::sync_with_stdio(false);cin.tie(0);
29 
30 
31     int T;
32     cin>>T;
33     while(T--)
34     {
35 
36     cin>>n>>m>>kk;
37     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j];
38 
39     for(int i=1;i<=n;i++)
40     {
41         for(int j=1;j<=m;j++)
42         {
43             f=0;
44             if(a[i][j]==0 && i+kk-1<=n && j+kk-1<=m)
45             {
46                 so(i,j,kk-1);
47             }
48             else f=1;
49             if(f==0) break;
50         }
51         if(f==0) break;
52     }
53 
54     if(f==0) cout<<"Yes"<<endl;
55     else cout<<"No"<<endl;
56 
57     }
58 
59     return 0;
60 }

 

1005,题目给你说的绕的超麻烦,看样例或模拟后找到规律即可

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <iomanip>
 5 #include <cstdio>
 6 #include <cstring>
 7 #include <cmath>
 8 using namespace std;
 9 typedef long long ll;
10 typedef unsigned long long ull;
11 const int maxn=1e6+5;
12 int a[maxn];
13 int t,n;
14 
15 int main()
16 {
17     scanf("%d",&t);
18     while(t--)
19     {
20         scanf("%d",&n);
21         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
22 
23         sort(a+1,a+1+n);
24         int cnt=0;
25         for(int i=2;i<=n;i++)
26         {
27             if(a[i]==a[i-1]) cnt++;
28         }
29 
30         printf("%d\n",cnt);
31     }
32 
33     return 0;
34 }

 

1006,排个序,贪心思想走下去即可。从短到长,后一个必须包含前一个才能继续,不用考虑字典序和相等时情况。另外数据小,不用kmp找,string::find函数方便找就行。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <map>
 5 using namespace std;
 6 
 7 struct px
 8 {
 9     string s;
10     int len;
11 }T[1005];
12 bool cmp(px aa,px bb)
13 {
14     return aa.len<bb.len;
15 }
16 
17 int main()
18 {
19     ios::sync_with_stdio(false); cin.tie(0);
20 
21     int t;
22     cin>>t;
23     while(t--)
24     {
25         int n;
26         cin>>n;
27         for(int i=1;i<=n;i++)
28         {
29             cin>>T[i].s;
30 
31             T[i].len=T[i].s.length();
32         }
33 
34         sort(T+1,T+1+n,cmp);
35 
36         int f=0;
37         string last=T[1].s;
38         for(int i=2;i<=n;i++)
39         {
40             if(T[i].s.find(last)!=string::npos) continue;
41             else { f=1; break;}
42 
43             last=T[i].s;
44         }
45         if(f) cout<<"No"<<endl;
46         else cout<<"Yes"<<endl;
47     }
48 
49     return 0;
50 }

 

1007,难题,防Ak

 

1008,重点,搜索题,单纯搜索的很好些,但这题要找到所有的方法,很容易超时!

(这题我历经了三个艰难阶段~~最后知道这是最短路条数模板题

1.最先想到的是dfs搜索所有路,如果没有障碍物那得搜索多少条啊我的天!

2.想了一会又想试试记忆化,但没办法啊它要回溯更新试试更多的路啊你把原先的标记返回了肯定是错的啊。

3.唉没办法,只能用专门的最短路贪心做法Dijkstra了,其实bfs本质就是Dijkstra,只不过权值为1更简单特殊化了!

暴力超时代码

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 using namespace std;
 7 typedef long long ll;
 8 const int maxn=1e6+5;
 9 const int mod=1000000007;
10 char a[1005][1005];
11 int vis[1005][1005],f[1005][1005];
12 int n,m;
13 int gx,gy;
14 int ans;
15 
16 void so(int x,int y)
17 {
18     if(x==gx && y==gy)
19     {
20         ans++;
21         ans%=mod;
22         return;
23     }
24 
25     //
26     if(y+1<=m && a[x][y+1]=='.' && vis[x][y+1]==0) { vis[x][y+1]=1; so(x,y+1); vis[x][y+1]=0; }
27 
28     //
29     if(x+1<=n && a[x+1][y]=='.' && vis[x+1][y]==0) { vis[x+1][y]=1; so(x+1,y); vis[x+1][y]=0; }
30 
31     //
32     if(x-1>=1 && a[x-1][y]=='.' && vis[x-1][y]==0) { vis[x-1][y]=1; so(x-1,y); vis[x-1][y]=0; }
33 
34     //
35     if(y-1>=1 && a[x][y-1]=='.' && vis[x][y-1]==0) { vis[x][y-1]=1; so(x,y-1); vis[x][y-1]=0; }
36 }
37 
38 int main()
39 {
40     ios::sync_with_stdio(false); cin.tie(0);
41 
42     int T;
43     cin>>T;
44     while(T--)
45     {
46         ans=0;
47         cin>>n>>m;
48         for(int i=1;i<=n;i++)
49         {
50             for(int j=1;j<=m;j++)
51             {
52                 cin>>a[i][j];
53             }
54         }
55         cin>>gx>>gy;
56 
57         vis[1][1]=1;
58         so(1,1);
59         vis[1][1]=0;
60 
61         if(ans) cout<<ans<<endl;
62         else cout<<"-1"<<endl;
63     }
64 
65     return 0;
66 }

Ac代码

dijkstra写法

  1 #include <iostream>
  2 #include <string>
  3 #include <algorithm>
  4 #include <iomanip>
  5 #include <vector>
  6 #include <queue>
  7 #include <cstdio>
  8 #include <cstring>
  9 using namespace std;
 10 const int maxn=550;//最大点数
 11 const int maxm=1e6+5;//最大边数
 12 const int inf=2100000000;
 13 const int mod=1000000007;
 14 int dist[maxn][maxn],vis[maxn][maxn];
 15 int cnt[maxn][maxn];
 16 char maze[maxn][maxn];
 17 int n,m,s;
 18 int ans,cntn;
 19 int gx,gy;
 20 int zh=(gx-1)*m+gy;
 21 
 22 struct px//存图结点信息
 23 {
 24     int tox;
 25     int toy;
 26     int w;
 27     px(){};
 28     px(int TOX,int TOY,int W):tox(TOX),toy(TOY),w(W){};
 29 };
 30 vector<px> vec[maxn][maxn];
 31 struct pxx//存所有相连的边的信息
 32 {
 33     int i;
 34     int j;
 35     int dist;
 36     bool operator<(const pxx &a) const
 37     {
 38         return dist>a.dist;
 39     }
 40     pxx(){};
 41     pxx(int I,int J,int DIST):i(I),j(J),dist(DIST){};
 42 };
 43 priority_queue<pxx> que;
 44 
 45 void Init()
 46 {
 47     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dist[i][j]=inf;
 48     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cnt[i][j]=0;
 49     memset(vis,0,sizeof(vis));
 50 }
 51 
 52 void Dijkstra(int x,int y)
 53 {
 54     dist[x][y]=0;
 55     que.push(pxx(x,y,0));
 56     cnt[x][y]=1;
 57                        
 58     while(!que.empty())
 59     {
 60         pxx tmp=que.top();
 61         que.pop();
 62         if(vis[tmp.i][tmp.j]) continue;
 63 
 64         vis[tmp.i][tmp.j]=1;
 65 
 66         cntn++;
 67         if(cntn==zh) break;
 68 
 69         for(int j=0;j<vec[tmp.i][tmp.j].size();j++)
 70         {
 71             int I=vec[tmp.i][tmp.j][j].tox,J=vec[tmp.i][tmp.j][j].toy,W=vec[tmp.i][tmp.j][j].w;
 72             if(!vis[I][J])
 73             {
 74                 if(dist[I][J]>dist[tmp.i][tmp.j]+W)
 75                 {
 76                     dist[I][J]=dist[tmp.i][tmp.j]+W;
 77                     que.push(pxx(I,J,dist[I][J]));
 78 
 79                     cnt[I][J]=cnt[tmp.i][tmp.j]%mod;
 80                 }
 81                 else if(dist[I][J]==dist[tmp.i][tmp.j]+W)
 82                 {
 83                     cnt[I][J]=(cnt[I][J]+cnt[tmp.i][tmp.j])%mod;
 84                 }
 85             }
 86         }
 87     }
 88 }
 89 
 90 int main()
 91 {
 92     ios::sync_with_stdio(false); cin.tie(0);
 93 
 94     int T;
 95     cin>>T;
 96     while(T--)
 97     {
 98         cin>>n>>m;
 99 
100         Init();//注意初始化无限大必须放在输入之前!
101         cntn=0;//多组输入时也要初始化
102         for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>maze[i][j];
103         cin>>gx>>gy;
104         for(int i=1;i<=n;i++)
105         {
106             for(int j=1;j<=m;j++)
107             {
108                 if(maze[i][j]=='.')
109                 {
110                     if(maze[i][j+1]=='.' && j+1<=m)
111                     {
112                         vec[i][j].push_back(px(i,j+1,1));
113                     }
114                     if(maze[i+1][j]=='.' && i+1<=n)
115                     {
116                         vec[i][j].push_back(px(i+1,j,1));
117                     }
118                     
119                     if(maze[i-1][j]=='.' && i-1>=1)
120                     {
121                         vec[i][j].push_back(px(i-1,j,1));
122                     }
123                     if(maze[i][j-1]=='.' && j-1>=1)
124                     {
125                         vec[i][j].push_back(px(i,j-1,1));
126                     }
127                 }
128             }
129         }
130 
131         Dijkstra(1,1);
132 
133         //for(int i=1;i<=n-1;i++) cout<<dist[i]<<' ';
134         if(cnt[gx][gy]) cout<<cnt[gx][gy]<<endl;
135         else cout<<"-1"<<endl;
136 
137         while(que.size()) que.pop();//多组输入时也要清空
138         for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) vec[i][j].clear();
139     }
140 
141     return 0;
142 }

bfs写法

  1 #include <iostream>
  2 #include <string>
  3 #include <algorithm>
  4 #include <iomanip>
  5 #include <vector>
  6 #include <queue>
  7 #include <cstdio>
  8 #include <cstring>
  9 using namespace std;
 10 const int maxn=550;//最大点数
 11 const int maxm=1e6+5;//最大边数
 12 const int inf=2100000000;
 13 const int mod=1000000007;
 14 int dist[maxn][maxn],vis[maxn][maxn];
 15 int cnt[maxn][maxn];
 16 int X[4]={0,1,-1,0};
 17 int Y[4]={1,0,0,-1};
 18 char maze[maxn][maxn];
 19 int n,m,s;
 20 int ans,cntn;
 21 int gx,gy;
 22 int zh=(gx-1)*m+gy;
 23 
 24 struct px//存图结点信息
 25 {
 26     int x;
 27     int y;
 28     px(){};
 29     px(int X,int Y):x(X),y(Y){};
 30 };
 31 
 32 queue<px> que;
 33 //二维,他就那可能连接的四条边,而且权值还都为1,所以不用再用个结构体优先队列去存了
 34 //那些存不定条数和权值很好,但存固定的这种简单的虽然也可以但大材小用了
 35 
 36 void Init()
 37 {
 38     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dist[i][j]=inf;
 39     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cnt[i][j]=0;
 40     memset(vis,0,sizeof(vis));
 41 }
 42 
 43 void bfs(int x,int y)
 44 {
 45     dist[x][y]=0;
 46     que.push(px(x,y));
 47     cnt[x][y]=1;
 48                        
 49     while(!que.empty())
 50     {
 51         px tmp=que.front();
 52         que.pop();
 53         if(vis[tmp.x][tmp.y]) continue;
 54         if(maze[tmp.x][tmp.y]!='.') continue;
 55 
 56         vis[tmp.x][tmp.y]=1;
 57 
 58         cntn++;
 59         if(cntn==zh) break;//两种break都可以,推荐1个
 60         //if(tmp.x==gx && tmp.y==gy) break;
 61         for(int i=0;i<=3;i++)
 62         {
 63             int I=tmp.x+X[i],J=tmp.y+Y[i];
 64             if(!vis[I][J] && maze[I][J]=='.' && I<=n && J<=m)
 65             {
 66                 if(dist[I][J]>dist[tmp.x][tmp.y]+1)
 67                 {
 68                     dist[I][J]=dist[tmp.x][tmp.y]+1;
 69                     que.push(px(I,J));
 70                     
 71                     cnt[I][J]=cnt[tmp.x][tmp.y]%mod;    
 72                 }
 73                 else if(dist[I][J]==dist[tmp.x][tmp.y]+1)
 74                 {
 75                     cnt[I][J]=(cnt[I][J]+cnt[tmp.x][tmp.y])%mod;
 76                 }
 77             }
 78         }
 79     }
 80 }
 81 
 82 int main()
 83 {
 84     ios::sync_with_stdio(false); cin.tie(0);
 85 
 86     int T;
 87     cin>>T;
 88     while(T--)
 89     {
 90         cin>>n>>m;
 91 
 92         Init();//注意初始化无限大必须放在输入之前!
 93         cntn=0;//多组输入时也要初始化
 94         for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>maze[i][j];
 95         cin>>gx>>gy;
 96 
 97         bfs(1,1);
 98 
 99         //for(int i=1;i<=n-1;i++) cout<<dist[i]<<' ';
100         if(cnt[gx][gy]) cout<<cnt[gx][gy]<<endl;
101         else cout<<"-1"<<endl;
102 
103         while(que.size()) que.pop();//多组输入时也要清空
104    
105     }
106 
107     return 0;
108 }

 

 

完。

posted @ 2018-11-04 11:30  RedBlack  阅读(194)  评论(0编辑  收藏  举报