3.12

http://codeforces.com/gym/101246

A题

B题

思路:简单模拟,对每一块砖判断它的前后左右是否比它高,如果比他高,它本身为0,否则它是他们的差值和。如果这块砖存在,就加上它的上下两个面。

 1 #include <iostream>
 2 #include<cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include<queue>
 6 #include <map>
 7 using namespace std;
 8 const int maxn=300;
 9 char s[maxn][maxn];
10 int a[maxn][maxn];
11 int b[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
12 int main()
13 {
14     freopen("input.txt","r",stdin);
15     freopen("output.txt","w",stdout);
16     int n,m;
17     while(~scanf("%d%d",&n,&m))
18     {
19         for(int i=0; i<n; i++)
20             scanf("%s",s[i]);
21         memset(a,0,sizeof(a));
22         for(int i=0; i<n; i++)
23         {
24             for(int j=0; j<m; j++)
25                 a[i+1][j+1]=s[i][j]-'0';
26         }
27         int ans=0;
28         for(int i=1; i<=n; i++)
29             for(int j=1; j<=m; j++)
30             {
31                 for(int k=0; k<4; k++)
32                 {
33                     int x=i+b[k][0];
34                     int y=j+b[k][1];
35                     if(a[x][y]<a[i][j])
36                         ans+=(a[i][j]-a[x][y]);
37                 }
38                 if(a[i][j])
39                 ans+=2;
40             }
41             printf("%d\n",ans);
42     }
43     return 0;
44 }
View Code

C题

思路:要用bitset去存储它的每一行所对应的列是否有*,然后dp得到最小的ans

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <map>
 7 #include <cmath>
 8 #include <bitset>
 9 #include <bits/stdc++.h>
10 using namespace std;
11 const int maxn=25;
12 bitset <maxn> f[maxn],dp[1<<maxn];
13 char s[26];
14 int id[1<<maxn],num[1<<maxn];
15 int lowbit(int x)
16 {
17     return x&-x;
18 }
19 int main()
20 {
21     freopen("input.txt","r",stdin);
22     freopen("output.txt","w",stdout);
23     int n,m;
24     scanf("%d%d",&n,&m);
25         for(int i=0;i<n;i++)
26         {
27             scanf("%s",s);
28             for(int j=0;j<m;j++)
29                 f[i][j]=s[j]=='*';
30         }
31         int ans=min(n,m);
32         for(int i=0;i<maxn;i++)
33         id[1<<i]=i;
34         for(int i=1;i<(1<<n);i++)
35         {
36             dp[i]=dp[i-lowbit(i)]|f[id[lowbit(i)]];
37             num[i]=num[i-lowbit(i)]+1;
38             ans=min(ans,max((int)dp[i].count(),n-num[i]));
39         }
40         printf("%d\n",ans);
41     return 0;
42 }
View Code

D题

思路:先由上往下进行存储每个城市被点燃的的最短时间,然后由下往上进行逐步推出从城市1出发是否能够在Vladimir控制时无路可走

 1 #include <iostream>
 2 #include<cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <vector>
 7 using namespace std;
 8 const int maxn=1500;
 9 vector<int> node[maxn];
10 queue<int> que;
11 int vis[maxn],pos[maxn],cnt[maxn];
12 int main()
13 {
14     //freopen("input.txt","r",stdin);
15     //freopen("output.txt","w",stdout);
16     int n,m,u,v;
17     while(~scanf("%d%d",&n,&m))
18     {
19         for(int i=0;i<m;i++)
20         {
21             scanf("%d%d",&u,&v);
22             node[u].push_back(v);
23             node[v].push_back(u);
24         }
25         memset(vis,0,sizeof(vis));
26         memset(cnt,0,sizeof(cnt));
27         memset(pos,0,sizeof(pos));
28         while(!que.empty()) que.pop();
29         que.push(1);
30         vis[1]=1;
31         int tot=0;
32         while(!que.empty())
33         {
34             int x=que.front();que.pop();
35             pos[++tot]=x;//从1开始依次经过的节点
36             for(int i=0;i<(int)node[x].size();i++)
37             {
38                 int k=node[x][i];
39                 if(vis[k]) continue;
40                 else
41                 {
42                     que.push(k);
43                     vis[k]=vis[x]+1;//城市k于城市x相连且城市x是城市k的上一级
44                 }
45             }
46         }
47         for(int i=n;i>=2;i--)
48         {
49             int k=pos[i];//从节点的最末尾开始依次往上进行搜索
50             for(int j=0;j<(int)node[k].size();j++)
51             {
52                 int x=node[k][j];
53                 if(vis[k]!=vis[x]+1) continue;
54                 if(cnt[k]==0) cnt[x]=1;//
55             }
56         }
57         if(cnt[1]==1)
58             printf("Vladimir\n");
59         else
60             printf("Nikolay\n");
61     }
62     return 0;
63 }
View Code

E题

思路:使用数组储存当前马车所走的第 i 个弯道,然后遍历所有路口进行下个距离的弯道 i +1进行储存,一直进行到 i +1=m结束

 1 #include <iostream>
 2 #include<cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include<queue>
 6 #include <map>
 7 using namespace std;
 8 const int maxn=400;
 9 int dp[maxn][maxn];
10 int a[maxn][maxn];
11 int ans[maxn],p[maxn];
12 int main()
13 {
14     freopen("input.txt","r",stdin);
15     freopen("output.txt","w",stdout);
16     int n,m;
17     while(~scanf("%d",&n))
18     {
19         for(int i=1; i<=n; i++)
20             for(int j=1; j<=n; j++)
21                 scanf("%d",&a[i][j]);
22         scanf("%d",&m);
23         for(int i=1; i<=m; i++)
24             scanf("%d",&p[i]);
25         memset(dp,0,sizeof(dp));
26         dp[0][1]=1;
27         for(int i=1; i<=m; i++)
28         {
29             for(int j=1; j<=n; j++)
30             {
31                 if(dp[i-1][j])
32                 {
33                     for(int k=1; k<=n; k++)
34                         if(a[j][k]==p[i])
35                             dp[i][k]=1;
36                 }
37             }
38         }
39         int k=0;
40         for(int i=1; i<=n; i++)
41             if(dp[m][i])
42                 ans[k++]=i;
43         printf("%d\n",k);
44         for(int i=0; i<k; i++)
45             printf("%d%c",ans[i],i==k-1?'\n':' ');
46     }
47     return 0;
48 }
View Code

F题

思路:题意是电梯当前所在楼层为m,上来n个人依次按下n个不同的楼层,电梯从1~n开始运行,如果在去往a[1]的过程中经过a[k],则在a[k]停了下来。利用从大到小和从小到大两个优先队列,对电梯的行进的途径楼层进行储存,然后放入结果数组,注意标记即可。

 1 #include <iostream>
 2 #include<cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include<queue>
 6 #include <map>
 7 using namespace std;
 8 const int maxn=300;
 9 int a[maxn];
10 int ans[maxn],flag[maxn];
11 priority_queue<int,vector<int>,greater<int> >que1;
12 priority_queue<int>que2;
13 int main()
14 {
15     freopen("input.txt","r",stdin);
16     freopen("output.txt","w",stdout);
17     int n,m;
18     while(~scanf("%d%d",&n,&m))
19     {
20         for(int i=0; i<n; i++)
21         {
22             scanf("%d",&a[i]);
23         }
24         while(!que1.empty())
25         {
26             que1.pop();
27         }
28         while(!que2.empty())
29         {
30             que2.pop();
31         }
32         memset(flag,0,sizeof(flag));
33         int p=0;
34         for(int i=0; i<n; i++)
35         {
36             if(flag[i])
37                 continue;
38             if(m>a[i])
39             {
40                 for(int j=i; j<n; j++)
41                     if(a[i]<=a[j]&&a[j]<=m&&!flag[j])
42                     {
43                         flag[j]=1;
44                         que2.push(a[j]);
45                     }
46                 while(!que2.empty())
47                 {
48                     ans[p++]=que2.top();
49                     que2.pop();
50                 }
51             }
52             if(m<=a[i])
53             {
54                 for(int j=i; j<n; j++)
55                     if(a[i]>=a[j]&&a[j]>=m&&!flag[j])
56                     {
57                         flag[j]=1;
58                         que1.push(a[j]);
59                     }
60                 while(!que1.empty())
61                 {
62                     ans[p++]=que1.top();
63                     que1.pop();
64                 }
65             }
66             m=a[i];
67         }
68         for(int i=0; i<n-1; i++)
69             printf("%d ",ans[i]);
70         printf("%d\n",ans[n-1]);
71     }
72     return 0;
73 }
View Code

G题

H题

I题

J题

思路:对每一个点都要对两点之间的距离进行遍历,利用三分找出两个点之间的距离,然后不断缩小范围求出最小的差的绝对值和此时的所在的位置

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <map>
 7 #include <cmath>
 8 using namespace std;
 9 const int maxn=500;
10 const double eps=1e-12;
11 double a[maxn];
12 int n,id;
13 double cal(double pre)
14 {
15     double len,len1;
16     len1=400000000;
17     for(int i=0; i<n; i++)
18     {
19         len=0;
20         for(int j=i+1; j<n; j++)
21         {
22             len+=fabs(a[i]+(j-i)*pre-a[j]);
23         }
24         for(int j=i-1; j>=0; j--)
25         {
26             len+=fabs(a[i]+(j-i)*pre-a[j]);
27         }
28         if(len<len1)
29         {
30             len1=len;
31             id=i;
32         }
33     }
34     return len1;
35 }
36 int solve()
37 {
38     scanf("%d",&n);
39     for(int i=0; i<n; i++)
40         scanf("%lf",&a[i]);
41     double  l=0,r=1000000;
42     while(r-l>=eps)
43     {
44         //printf("%.5lf\n",cal(l));
45         double mid=(r+l)/2.0;
46         double midd=(mid+r)/2.0;
47         if(cal(mid)>cal(midd)) l=mid;
48         else r=midd;
49     }
50     double pre=cal(l)<cal(r)?l:r;
51     double len;
52     len=cal(pre);
53     printf("%.4lf\n",len);
54     for(int i=0; i<n; i++)
55     {
56         printf("%.10lf%c",a[id]+(i-id)*pre,i==n-1?'\n':' ');
57     }
58     return 0;
59 }
60 int main()
61 {
62     freopen("input.txt","r",stdin);
63     freopen("output.txt","w",stdout);
64     solve();
65     return 0;
66 }
View Code

K题

L题

posted @ 2017-03-15 20:42  Wally的博客  阅读(107)  评论(0编辑  收藏  举报