A
http://codeforces.com/contest/514/problem/A
题意为给定一个最多18位的数,然后改变每一位的数字也可以不改变,改变的规则是 当前数字是t,那么可以替换为9-t, 是减法,当然也可以选择不替换,且替换后的整个数不能有前导0,问经过替换或者不替换后的最小正整数是多少。
比如 27 替换后22 4545 替换后为 4544 9999替换后为9000
单独处理第一个数字,保证不为0,剩下位选择min(t,9-t) 就可以了。
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <stdlib.h> #include <cmath> #include <iomanip> #include <vector> #include <set> #include <map> #include <stack> #include <queue> #include <cctype> #define rd(x) scanf("%d",&x) #define rd2(x,y) scanf("%d%d",&x,&y) #define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z) using namespace std; typedef long long ll; ll n; int dig[20]; int ans[20]; int len; int main() { while(cin>>n) { len=0; while(n) { dig[len++]=n%10; n/=10; } if(dig[len-1]==9) cout<<9; else cout<<min(dig[len-1],9-dig[len-1]); for(int i=len-2;i>=0;i--) { cout<<min(dig[i],9-dig[i]); } cout<<endl; } return 0; }
B
http://codeforces.com/contest/514/problem/B
题意为给定一个初始点的坐标,然后给出n个点的坐标,问最少有多少条经过初始点的直线可以把所有的点全部覆盖掉。
求有多少斜率就可以了,竖线单独考虑。
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <stdlib.h> #include <cmath> #include <iomanip> #include <vector> #include <set> #include <map> #include <stack> #include <queue> #include <cctype> #define rd(x) scanf("%d",&x) #define rd2(x,y) scanf("%d%d",&x,&y) #define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z) using namespace std; typedef long long ll; map<double,int>mp; const int maxn=1010; int n; int xx,yy; int x,y; bool flag; int main() { while(cin>>n>>xx>>yy) { mp.clear(); flag=0; for(int i=1;i<=n;i++) { scanf("%d%d",&x,&y); if(x==xx) { flag=1; continue; } double p=1.0*(y-yy)/(x-xx); mp[p]++; } if(flag) cout<<mp.size()+1<<endl; else cout<<mp.size()<<endl; } return 0; }
http://codeforces.com/contest/514/problem/C
题意为给定n个只包含a,b,c三个字母的字符串,然后有m个查询,每个查询包含一个字符串,问该字符串能否与之前n个字符串的某个字符串匹配成功,匹配成功的条件是:字符串的长度相同且不同的字母有且仅有一个,比如 aabc 和 aaac就是匹配成功的,注意aabc 和 aabc是不匹配成功的,必须有一个字母不同。
对n个字符串建立字典树,然后每个查询用dfs查找就可以了。
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <stdlib.h> #include <cmath> #include <iomanip> #include <vector> #include <set> #include <map> #include <stack> #include <queue> #include <cctype> #define rd(x) scanf("%d",&x) #define rd2(x,y) scanf("%d%d",&x,&y) #define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z) using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=600010; char str[maxn]; bool haslen[maxn]; int n,m; bool ok; struct Trie { Trie*next[3]; bool cnt; Trie() { for(int i=0;i<3;i++) next[i]=NULL; cnt=0; } }; void insert(char *s,Trie &root)//注意&root是引用 { Trie *p=&root; int len=strlen(s); for(int i=0;i<len;i++) { int id=s[i]-'a'; if(p->next[id]==NULL) p->next[id]=new Trie(); p=p->next[id]; } p->cnt=1; } void dfs(Trie *p,bool changed,int curlen,int len)//在字典树p中查找,changed代表是否已经改变一个字母,curlen当前匹配的字符串长度,len总长度 { if(curlen==len) { if(changed&&p->cnt)//已经改变了一个字母且到达了字典树的叶子结点,说明查找到了 ok=1; return; } for(int i=0;i<3;i++)//当前位置字母可以替换为其他两个,也可以不变 { if(p->next[i]!=NULL) { if(str[curlen]-'a'==i)//当前字母不变 { dfs(p->next[i],changed,curlen+1,len); } else//替换为其他两个字母 { if(changed)//题目要求只改变一个字母,已经改变过了,就不行了 continue; dfs(p->next[i],1,curlen+1,len); } } } } int main() { while(rd2(n,m)!=EOF) { memset(haslen,0,sizeof(haslen)); Trie root; for(int i=1;i<=n;i++) { scanf("%s",str); int len=strlen(str); haslen[len]=1; insert(str,root); } for(int i=1;i<=m;i++) { scanf("%s",str); int len=strlen(str); if(!haslen[len]) { printf("NO\n"); continue; } ok=0; dfs(&root,0,0,len); if(ok) printf("YES\n"); else printf("NO\n"); } } return 0; }