CF 812 ABC
来源:互联网 发布:咬人猫年龄 知乎 编辑:程序博客网 时间:2024/06/11 17:06
哭诉:
和省赛队友在宿舍的自习室打的。本来过了A。B莫名的被卡,当时没注意C,打完发现C居然是最好做的.比赛快结束的时候A题又被Hack,于是0题滚粗。QaQ!
A题:http://codeforces.com/contest/812/problem/A
题意:一个十字路口,请你判断是否会出现相撞的情况,个人感觉是道卡题意的题。
思路:考虑四条路有没有行人,如果有那么这条路上车不能走,它的上一个路口不能右拐,下一个路口不能左拐,对面的路口不能直行!
#include <iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<queue>int a[4][4];int main(){ bool flag=0; for(int i=1;i<=4;++i) { for(int j=1;j<=4;++j) { scanf("%d",&a[i][j]); } if(a[i][4]&&(a[i][1]||a[i][2]||a[i][3])) flag=1; } if(a[1][4]&&(a[2][1]||a[3][2]||a[4][3])) flag=1; if(a[2][4]&&(a[1][3]||a[3][1]||a[4][2])) flag=1; if(a[3][4]&&(a[2][3]||a[4][1]||a[1][2])) flag=1; if(a[4][4]&(a[1][1]||a[3][3]||a[2][2])) flag=1; if(flag) printf("YES\n"); else printf("NO\n"); return 0;}
B题:http://codeforces.com/contest/812/problem/B
题意:一个人从图的左下角出发,每次到上一层必须经过最左边点或者最右边的点,每走一格需要一个的时间,问怎么样才能遍历所有的1.
做法:
1.直接dfs记录当前的位置以及所用的时间,这里的vis最多走两遍,所以当vis为0,1的时候都可以走。然后剪剪枝就行了,当时先用的dfs做的,然后读地图的时候读错了,以为自己的dfs炸了。就换了下面的做法
2.细细一想这似乎可以用dp啊。
dp[i][0] 到当前楼最左边的最小步数 dp[i][1] 到当前楼最右边的步数 i代表着层数
所以会有这样的转移方程,l[i] ,r[i]分别表示这层楼最左边的1,和最右边的1. m+2是这层楼的长度
dp[i][0]=min(dp[i+1][0]+2*r[i+1]+1,dp[i+1][1]+m+2);
dp[i][1]=min(dp[i+1][0]+m+2,dp[i+1][1]+2*(m+1-l[i+1])+1);
这个时候细心的人就会发现:
1.如果走到当前层,上面的所有层都没有1了dp不就应该停了么!!!
2.如果走到当前层,这层没有1。就应该直接去上一层呀。
因为这两点比赛的时候wa了五六回,补题的时候又弄了几个小时!!!
#include <iostream>#include<stdio.h>#include<string.h>using namespace std;int main(){ int n,m; int dp[20][2]; int l[20],r[20]; int lig[20]; memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); memset(dp,0,sizeof(dp)); memset(lig,0,sizeof(lig)); scanf("%d%d",&n,&m); char s[105]; int sum=0; for(int i=1;i<=n;++i) { scanf("%s",s); int len=strlen(s); for(int j=0;j<len;++j) { if(s[j]=='1') { sum++; lig[i]++; if(l[i]==0) l[i]=j; r[i]=j; } } } int pos=0; for(int i=1;i<=n;++i) { if(lig[i]!=0) { pos=i; break; } } if(pos==n) { printf("%d\n",r[pos]); return 0; } dp[n-1][0]=2*r[n]+1; dp[n-1][1]=m+2; for(int i=n-2;i>=1;--i) { if(lig[i+1]==0) { dp[i][0]=dp[i+1][0]+1; dp[i][1]=dp[i+1][1]+1; } else { dp[i][0]=min(dp[i+1][0]+2*r[i+1]+1,dp[i+1][1]+m+2); dp[i][1]=min(dp[i+1][0]+m+2,dp[i+1][1]+2*(m+1-l[i+1])+1); } if(i==pos) break; } printf("%d\n",min(dp[pos][0]+r[pos],dp[pos][1]+(m+1-l[pos]))); return 0;}
C http://codeforces.com/contest/812/problem/C
题意:有一定的商品每件商品都有一个初始价格,和一个标号。你有s块钱,当你购买k件物品时,每个物品的价钱变成 初始价钱+ 标号乘以k。
做法:二分,每次判断的时候就给开个数组算下当前的价格排序,判断一下可以是否可以购买这么多件物品。
感觉自己的二分写完总是大于答案1或者等于答案,郁闷啊,有没有大神指点一下
#include<bits/stdc++.h>using namespace std;int a[100100];int b[100100];int s,n;bool judge(int mid){ if(mid>n) return 0; int cost=s; for(int i=0;i<n;++i) { b[i]=a[i]+(i+1)*mid; } sort(b,b+n); for(int i=0;i<mid;++i) { cost=cost-b[i]; if(cost<0) return 0; } if(cost<0) return 0; return 1;}int main(){ memset(a,0,sizeof(a)); scanf("%d%d",&n,&s); for(int i=0;i<n;++i) { scanf("%d",&a[i]); } int l=0,r=n; long long ans=0; while(l<r) { int mid=l+(r-l)/2; if(judge(mid)) l=mid+1; else r=mid-1; } while(judge(l)==0) l--; for(int i=0;i<n;++i) b[i]=a[i]+(i+1)*l; sort(b,b+n); for(int i=0;i<l;++i) ans=ans+(long long)b[i]; printf("%d %I64d\n",l,ans); return 0;}
- CF 812 ABC
- cf 121 ABC
- CF #406 div1 ABC
- Edu CF #R8(ABC)
- cf div2 #453 ABC(D)
- cf div2 #444 (ABC)(D已补)
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- abc
- mac下安装python包管理器
- 安卓刷机常识和教程
- 注册表读写
- [Leetcode] 165. Compare Version Numbers 解题报告
- python——刷票脚本
- CF 812 ABC
- 人脸识别方向论文笔记(2)-- Latent Factor Guided Convolutonal Neural Networks for Age-Invariant Face Recognition
- android 中back两种退出app的方法
- 第二章 操作文件和目录
- HTML内部文本的基本结构及注释
- react-native使用Swiper在安卓上不显示
- C#图像处理(剪切、合成、缩略)
- mac 下配置maven
- LC Binary-Search summary