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 }
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 }
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 }
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 }
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 }
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 }
K题
L题