小比赛
密码:123456
1001 http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1001&cid=16288&hide=0
模拟题目,不过在pos赋初值的时候弄错了,我的pos要的到的值是0-n-1而我给赋值成0了,因为我要用它来判断。所以纠结了老久了才检查到。
这种错误很难找的。提醒一下自己认真!
#include <cstdio> #include <cstring> #include <iostream> #define maxn 5007 using namespace std; int a[maxn],b[maxn]; int n,m; int main() { int ti,i; int x,y; char op[2]; scanf("%d",&ti); while (ti--) { scanf("%d%d",&n,&m); n /= 2; for (i = 0; i < n; ++i) a[i] = i; for (i = n ; i < 2*n; ++i) b[i - n] = i; while (m--) { scanf("%s%d",op,&x); x--; if (op[0] == 'Q') { int pos = 0; for (i = 0; i < n; ++i) { if (a[i] == x) { pos = i; break; } } if (i < n) printf("%d %d %d\n",a[(pos - 1 + n)%n] + 1,a[(pos + 1)%n] + 1,b[pos] + 1); else { for (i = 0; i < n; ++i) { if (b[i] == x) { pos = i; break; } } printf("%d %d %d\n",b[(pos - 1 + n)%n] + 1,b[(pos + 1)%n] + 1,a[pos] + 1); } } else { scanf("%d",&y); y--; if (op[0] == 'A') { int pos1 = 0,pos2 = 0; for (i = 0; i < n; ++i) { if (a[i] == x) { pos1 = i; break; } } if (i < n) { for (i = 0; i < n; ++i) { if (b[i] == y) { pos2 = i; break; } } } else { for (i = 0; i < n; ++i) { if (a[i] == y) { pos1 = i; break; } } for (i = 0; i < n; ++i) { if (b[i] == x) { pos2 = i; break; } } } int t = a[pos1]; a[pos1] = b[pos2]; b[pos2] = t; } else if (op[0] == 'B') { int pos1 = -1,pos2 = -1; for (i = 0; i < n; ++i) { if (a[i] == x) pos1 = i; if (a[i] == y) pos2 = i; if (pos1 > -1&&pos2 > -1) break; } if (i < n) { int t = a[pos1]; a[pos1] = a[pos2]; a[pos2] = t; } else { int pos1 = -1,pos2 = -1;//就是这里赋初值的时候弄错了 for (i = 0; i < n; ++i) { if (b[i] == x) pos1 = i; if (b[i] == y) pos2 = i; if (pos1 > -1&&pos2 > -1) break;//因为这里要判断的 } int t = b[pos1]; b[pos1] = b[pos2]; b[pos2] = t; } } } } } return 0; }
1002笛卡尔树,还没研究。http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1002&cid=16288&hide=0
1003:http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1003&cid=16288&hide=0
暴力做的,才开始我是记录的所有前两个字符串s1 s2搜索到的四进制形式,然后与四进制s3比较,这样相当麻烦,写了一晚上没A.后来改成十进制,求和后然后在转化成4进制与四进制s3比较,可是还是WA最后虎哥提醒了一组数据???12 与 312如果最后还是四进制比较的话很麻烦不好写。转化思路,本来我以为3个dfs记录所有搜到的十进数,要O(n^3)可是虎哥提醒第三组数据hash[]就行,才恍然大悟,只需O(n^2)即可,hash[i]来表示i是否存在。
#include <cstdio> #include <cstring> #include <iostream> #define maxn 4097 #define N 10 using namespace std; int res1[maxn],res2[maxn],res3[maxn*2]; int r1,r2; char s1[N],s2[N],s3[N]; int len1,len2,len3; void dfs1(int num) { if (num == len1 - 1) { for (int k = 0; k < len1; ++k) { res1[r1] = res1[r1]*4 + s1[k] - '0'; } r1++; return ; } if (s1[num + 1] != '?') dfs1(num + 1); else { for (int i = 0; i <= 3; ++i) { s1[num + 1] = i + '0'; dfs1(num + 1); s1[num + 1] = '?'; } } } void dfs2(int num) { if (num == len2 - 1) { for (int k = 0; k < len2; ++k) { res2[r2] = res2[r2]*4 + s2[k] - '0'; } r2++; return ; } if (s2[num + 1] != '?') dfs2(num + 1); else { for (int i = 0; i <= 3; ++i) { s2[num + 1] = i + '0'; dfs2(num + 1); s2[num + 1] = '?'; } } } void dfs3(int num) { if (num == len3 - 1) { int sum = 0; for (int k = 0; k < len3; ++k) { sum = sum*4 + s3[k] - '0'; } res3[sum] = 1; return ; } if (s3[num + 1] != '?') dfs3(num + 1); else { for (int i = 0; i <= 3; ++i) { s3[num + 1] = i + '0'; dfs3(num + 1); s3[num + 1] = '?'; } } } int main() { int i,j; // printf("%c",1 + '0'); while (~scanf("%s",s1)) { r1 = r2 = 0; scanf("%s",s2); scanf("%s",s3); len1 = strlen(s1); len2 = strlen(s2); len3 = strlen(s3); memset(res1,0,sizeof(res1)); memset(res2,0,sizeof(res2)); memset(res3,0,sizeof(res3)); //搜做第一个字符串的所有可能 if (s1[0] != '?') dfs1(0); else { for (j = 0; j <= 3; ++j) { s1[0] = j + '0'; dfs1(0); s1[0] = '?'; } } /* printf("%d\n",r1); for (i = 0; i < r1; ++i) printf("%d\n",res1[i]); printf("****************************\n");*/ //搜做第二个字符串的所有可能 if (s2[0] != '?') dfs2(0); else { for (j = 0; j <= 3; ++j) { s2[0] = j + '0'; dfs2(0); s2[0] = '?'; } } /*printf("%d\n",r2); for (i = 0; i < r2; ++i) printf("%d\n",res2[i]); printf("****************************\n");*/ //搜做第二个字符串的所有可能 if (s3[0] != '?') dfs3(0); else { for (j = 0; j <= 3; ++j) { s3[0] = j + '0'; dfs3(0); s3[0] = '?'; } } //检验 int ct = 0; for (i = 0; i < r1; ++i) { for (j = 0; j < r2; ++j) { int tmp = res1[i] + res2[j]; if (res3[tmp]) ct++; } } printf("%d\n",ct); } return 0; }
1004 http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1004&cid=16253&hide=0
就是裸的求反素数:
#include <cstdio> #include <cstring> #define ll long long using namespace std; const int inf = 999999999; const int prime[16]= {1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; int n; ll bnum,bsum; void getantiprime(ll num,ll k,ll sum,ll limit) { if (bsum < sum) { bsum = sum; bnum = num; } if (bsum == sum && bnum > num) bnum = num; if (k > 10) return ; ll tmp = num; for (int i = 1; i <= limit; ++i) { if (tmp*prime[k] > n) break; tmp = tmp*prime[k]; getantiprime(tmp,k + 1,sum*(i + 1),i); } } int main() { int t; scanf("%d",&t); while (t--) { bsum = -inf; bnum = inf; scanf("%d",&n); getantiprime(1,1,1,50); printf("%lld\n",bnum); } return 0; }
1005http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1005&cid=16288&hide=0
字典树做法:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define maxn 50007 using namespace std; struct node { int flag; node *next[27]; }*head,H[100000]; int n,m,pos; char str[maxn][23]; node* newnode() { node *q = &H[pos++]; for (int i = 0; i< 26; ++i) q->next[i] = NULL; q->flag = 0; return q; } void insert(char *s) { int i,k; int len = strlen(s); node *p = head; for (i = 0; i < len; ++i) { k = s[i] - 'a'; if (p->next[k] == NULL) p->next[k] = newnode(); p = p->next[k]; } p->flag = 1; } bool search(char *s) { int i,k; int len = strlen(s); node *p = head; for (i = 0; i < len; ++i) { k = s[i] - 'a'; if (p->next[k]) p = p->next[k]; else return false; } if (p->flag) return true; else return false; } int main() { int i; while (~scanf("%d%d",&n,&m)) { memset(H,0,sizeof(H)); pos = 0; head = &H[pos++]; for (i = 0; i < n; ++i) { cin>>str[i]; } // for (i = 0; i< n; ++i) printf("%s\n",str[i]); char tmp[23]; for (i = 0; i < m; ++i) { scanf("%s",tmp); insert(tmp); } int ct = 0; for (i = 0; i < n; ++i) { if (!search(str[i])) { insert(str[i]); ct++; } } printf("%d\n",ct); } return 0; }
set做法:
#include <iostream> #include <string> #include <cstdio> #include <map> #include <set> #define maxn 50010 using namespace std; set<string>S; string str[maxn]; int main() { int n,m; while (~scanf("%d%d",&n,&m)) { S.clear(); for (int i = 0; i < n; ++i) cin>>str[i]; string s; int ct = 0; for (int i = 0; i < m; ++i) { cin>>s; S.insert(s); } for (int i = 0; i < n; ++i) { if (S.find(str[i]) == S.end()) { S.insert(str[i]); ct++; } } printf("%d\n",ct); } return 0; }
map做法:
#include <iostream> #include <string> #include <cstdio> #include <map> #include <set> #define maxn 50010 using namespace std; map <string,int> mp; string str[maxn]; int main() { int n,m; while (~scanf("%d%d",&n,&m)) { mp.clear(); for (int i = 0; i < n; ++i) cin>>str[i]; string s; int ct = 0; for (int i = 0; i < m; ++i) { cin>>s; mp[s] = 1; } for (int i = 0; i < n; ++i) { if (!mp[str[i]]) { ct++; mp[str[i]] = 1; } } printf("%d\n",ct); } return 0; }