题目:http://acm.hdu.edu.cn/showproblem.php?pid=4320
题意:给一个A进制的有限小数,问是否可以转换为B进制的有限小数。
这道题目是真心不懂,即使看了解题报告也不知道怎么个情况,就知道一条结论:A的所有质因子都包含在B中,则可以转换。但具体怎么证明,纠结 ~ing。表示打表我怎么都WA(可能是表打错了给)童鞋提示用 gcd 不断的去降 a。想想也是,既然要求a 的所有质因子是否都含在b中,那么不断的求他们的最大公约数,然后降 a ,直到他们的公约数 <= 1这时判断 a,如果a为 1那么就是a的所有质因子都在b中
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <queue> 5 #include <stack> 6 #include <algorithm> 7 #include <math.h> 8 #define N 200 9 #define M 100 10 #define _clr(a,val) (memset(a,val,sizeof(a))) 11 12 using namespace std; 13 14 typedef long long ll; 15 ll gcd(ll a,ll b) 16 { 17 if(!b) return a; 18 else return gcd(b,a % b); 19 } 20 int main() 21 { 22 ll a,b; 23 int t; 24 int cs = 0; 25 scanf("%d",&t); 26 while(t--) 27 { 28 cin>>a>>b; 29 printf("Case #%d: ",++cs); 30 ll c = gcd(a,b); 31 while(c > 1) 32 { 33 a /= c; 34 c = gcd(a,b); 35 } 36 if(a == 1) printf("YES\n"); 37 else printf("NO\n"); 38 } 39 return 0; 40 }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4323
题意:定义编辑距离,然后给出一些关键字,最后给出一些询问q ,dis,看给的关键字里有几个是经过 d 步可以变为 q 的,其中 d <= dis
思路:dp求解编辑距离,然后与dis 比较。比赛的时候是求的最长的公共子序列,然后就悲剧的wa,后来发现少考虑了一些情况,今天看了一下标程,原来它是求的最短不同序列
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <iostream> 5 #define N 2000 6 #define M 20 7 #define _clr(a,val) (memset(a,val,sizeof(a))) 8 9 using namespace std; 10 11 struct node 12 { 13 char str[M]; 14 int len; 15 }a[N]; 16 char sbr[M]; 17 int dp[M][M]; 18 void dplen(char s[],char t[],int len1,int len2) 19 { 20 _clr(dp,0); 21 int i,j; 22 for(i = 0; i <= len1; i++) 23 dp[i][0] = i; 24 for(j = 0; j <= len2; j++) 25 dp[0][j] = j; 26 int flag; 27 for(i = 1; i <= len1; i++) 28 { 29 for(j = 1; j <= len2; j++) 30 { 31 if(s[i - 1] == t[j - 1]) 32 { 33 flag = 0; 34 } 35 else flag = 1; 36 dp[i][j] = min(min(dp[i - 1][j - 1] + flag,dp[i - 1][j] + 1),dp[i][j - 1] + 1); 37 } 38 } 39 } 40 int main() 41 { 42 int i; 43 int cs = 0; 44 int t; 45 int n,m; 46 //freopen("data.txt","r",stdin); 47 scanf("%d",&t); 48 while(t--) 49 { 50 scanf("%d%d",&n,&m); 51 for(i = 0; i < n; i++) 52 { 53 getchar(); 54 scanf("%s",a[i].str); 55 a[i].len = strlen(a[i].str); 56 } 57 printf("Case #%d:\n",++cs); 58 int dis; 59 while(m--) 60 { 61 int ans = 0; 62 scanf("%s%d",sbr,&dis); 63 int len1 = strlen(sbr); 64 for(i = 0; i < n; i++) 65 { 66 dplen(a[i].str,sbr,a[i].len,len1); 67 if(dp[a[i].len][len1] <= dis) 68 ans++; 69 } 70 printf("%d\n",ans); 71 } 72 } 73 return 0; 74 }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4324
题意:从图中找出任何三个人构成一个环(任何两个人之间都只有一条单向路,题目里明确说明有如果 A don't love B, then B must love A。)
思路:把喜欢自己的定义入度,假设到了第n+1个人 那么前n个人 两两之间必须存在一个喜欢指向 不考虑其它的话他们的入度和 为(n-1)*n/2 如果比这个大 那说明 有其他人k喜欢这里面的人 那个人k一定是第n+1个人喜欢的 所以有Triangle LOVE
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <queue> 5 #include <stack> 6 #include <algorithm> 7 #include <math.h> 8 #define N 2010 9 #define M 100 10 #define _clr(a,val) (memset(a,val,sizeof(a))) 11 12 using namespace std; 13 14 int like[N]; 15 int sum; 16 char map[N][N]; 17 int main() 18 { 19 int t,n; 20 int i,j; 21 int cs = 0; 22 //freopen("data.txt","r",stdin); 23 scanf("%d",&t); 24 while(t--) 25 { 26 _clr(map,0); 27 _clr(like,0); 28 scanf("%d",&n); 29 for(i = 0; i < n; i++) 30 { 31 getchar(); 32 scanf("%s",map[i]); 33 } 34 int flag = 0; 35 for(i = 0; i < n; i++) 36 { 37 sum = 0; 38 for(j = 0; j < i; j++) 39 { 40 if(map[j][i] == '1') sum += like[j]; 41 } 42 //cout<<"sum = "<<sum<<endl; 43 if(sum > ((i - 1) * i / 2)) 44 { 45 flag = 1;break; 46 } 47 //like[i] = 0; 48 for(j = 0; j < n; j++) 49 { 50 if(map[i][j] == '0' && i != j) 51 like[i]++; 52 } 53 //cout<<"like[i] = "<<like[i]<<endl; 54 } 55 if(flag) printf("Case #%d: Yes\n",++cs); 56 else printf("Case #%d: No\n",++cs); 57 } 58 return 0; 59 }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4325
题意:给出N 和 M ,然后是N 个时间段,M 个询问,第 i 行表示 第 i 朵花 开放时间和凋谢的时间,然后询问是一个时间点,问在这个时间点有多少种花在开放。
看到这道题目,想起了HDU 1556 color the ball http://acm.hdu.edu.cn/showproblem.php?pid=1556,一样的题目。线段树染色询问的一种变形,数据给的需要离散化,其他的也没什么。不过可能是数据问题,用树状数组不进行离散化也是可以的
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <queue> 5 #include <stack> 6 #include <algorithm> 7 #include <math.h> 8 #define N 100000 9 #define M 100 10 #define _clr(a,val) (memset(a,val,sizeof(a))) 11 12 using namespace std; 13 14 int coun[N]; 15 void insert(int x,int val) 16 { 17 while(x < N) 18 { 19 coun[x] += val; 20 x += (x & (-x)); 21 } 22 } 23 int quey(int x) 24 { 25 int sum = 0; 26 while(x > 0) 27 { 28 sum += coun[x]; 29 x -= (x & (-x)); 30 } 31 //cout<<"sum = "<<sum<<endl; 32 return sum; 33 } 34 int main() 35 { 36 int s,t; 37 int n,m; 38 int tt,x; 39 int cs = 0; 40 int i; 41 //freopen("data.txt","r",stdin); 42 scanf("%d",&tt); 43 while(tt--) 44 { 45 _clr(coun,0); 46 scanf("%d%d",&n,&m); 47 for(i = 0; i < n; i++) 48 { 49 scanf("%d%d",&s,&t); 50 insert(s,1); 51 insert(t + 1,-1); 52 } 53 printf("Case #%d:\n",++cs); 54 for(i = 0; i < m; i++) 55 { 56 scanf("%d",&x); 57 int ans = quey(x); 58 printf("%d\n",ans); 59 //cout<<ans<<endl; 60 } 61 } 62 return 0; 63 }
标程是先对输入的时间点和询问点进行离散化后,只保留那些没有重复的数值,然后建树,插入,询问
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #define N 100010 6 #define _clr(a,val) (memset(a,val,sizeof(a))) 7 8 using namespace std; 9 10 struct node 11 { 12 int l; 13 int r; 14 int num; 15 }tr[N]; 16 int ttr[N * 2]; // 用来保存输入的时间段的起始点和终止点和询问的时间点 17 int s[N],e[N],q[N]; 18 int cnt; 19 void build(int s,int e,int d) 20 { 21 tr[d].num = 0; 22 tr[d].l = s; 23 tr[d].r = e; 24 if(s == e) return ; 25 build(s,(s + e) / 2,d * 2); 26 build((s + e) / 2 + 1,e,d * 2 + 1); 27 } 28 void insert(int s,int e,int d) 29 { 30 if(s <= tr[d].l && e >= tr[d].r) 31 { 32 tr[d].num ++; 33 return ; 34 } 35 else 36 { 37 if(tr[d].num > 0) 38 { 39 tr[d * 2].num += tr[d].num; 40 tr[d * 2 + 1].num += tr[d].num; 41 tr[d].num = 0; 42 } 43 if(s <= tr[d * 2].r) insert(s,e,d * 2); 44 if(e >= tr[d * 2 + 1].l) insert(s,e,d * 2 + 1); 45 } 46 } 47 int quey(int d,int x) 48 { 49 if(tr[d].l == tr[d].r) 50 { 51 return tr[d].num; 52 } 53 else 54 { 55 if(tr[d].num > 0) 56 { 57 tr[d * 2].num += tr[d].num; 58 tr[d * 2 + 1].num += tr[d].num; 59 tr[d].num = 0; 60 } 61 if(x <= tr[d * 2].r) return quey(d * 2,x); 62 else return quey(d * 2 + 1,x); 63 } 64 } 65 int main() 66 { 67 int i; 68 int cs = 0; 69 int t,n,m; 70 //freopen("data.txt","r",stdin); 71 scanf("%d",&t); 72 while(t--) 73 { 74 scanf("%d%d",&n,&m); 75 cnt = 0; 76 _clr(ttr,0); 77 _clr(s,0); 78 _clr(e,0); 79 for(i = 0; i < n; i++) 80 { 81 scanf("%d%d",&s[i],&e[i]); 82 ttr[cnt++] = s[i]; 83 ttr[cnt++] = e[i]; 84 } 85 for(i = 0; i < m; i++) 86 { 87 scanf("%d",&q[i]); 88 ttr[cnt++] = q[i]; 89 } 90 printf("Case #%d:\n",++cs); 91 sort(ttr,ttr + cnt); 92 cnt = unique(ttr,ttr + cnt) - ttr; // 利用库函数(去重)把一些重复的点去除掉,经过转换,ttr数组内保存的都是不一样的真正需要的数值 93 build(1,cnt,1); // 建树 94 for(i = 0; i < n; i++) 95 { 96 s[i] = lower_bound(ttr,ttr + cnt,s[i]) - ttr + 1; // 利用库函数(二分查找返回相同元素下界)找到离散化后原先点所在新数组中的位置 97 e[i] = lower_bound(ttr,ttr + cnt,e[i]) - ttr + 1; 98 insert(s[i],e[i],1); 99 } 100 for(i = 0; i < m; i++) 101 { 102 q[i] = lower_bound(ttr,ttr + cnt,q[i]) - ttr + 1; // 同样返回询问点新位置 103 int ans = quey(1,q[i]); 104 printf("%d\n",ans); 105 } 106 } 107 }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4329
题意:真心不想说这个题目出的真让人恶心,定义的计算公式里面的用到的变量描述的简直让人读的晕晕的,读了N+遍也没有猜出样例怎么弄,还是童鞋给说的那个Avep怎么计算才知道的。
建议这道题目去看标程,然后你会很清楚那些量怎么算的。简单说一下题意吧,首先是Avep怎么计算,首先都知道上面N行给出的是一个对照表,下面N行给出的是计算用到的表,对下面N行的每一行里面那些检索出来的URL,如果前 i 个URL 里面 包含对照表里给的 URL j 个,那么就用 j / i ,把这个数值累加,一直到该行的URL全部与对照表中的URL比较完。然后再用求 的这个值 假设是 ans ,上面对应的对照表中给出的 URL个数为 num,那么再用 ans / num,这个值成为该行的 Avep 值,这样计算出 N个 Avep 值,累加后除以 N 即为结果。现在题意已经说完。题目一点不难,稍带着字符串的处理,但就纠结在了读题上,怎么都绕不过来题目的意思。
深感库函数的强大和便利
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <iostream> 5 #include <string> 6 #include <sstream> 7 #include <map> 8 #define N 110 9 #define M 10010 10 #define _clr(a,val) (memset(a,val,sizeof(a))) 11 12 using namespace std; 13 14 map<string,int> mp; 15 char str[N][M]; 16 char sbr[N][M]; 17 int main() 18 { 19 int i,n,t; 20 int cs = 0; 21 //freopen("data.txt","r",stdin); 22 scanf("%d",&t); 23 while(t--) 24 { 25 scanf("%d",&n); 26 getchar(); 27 for(i = 0; i < n; i++) 28 cin.getline(str[i], M); 29 for(i = 0; i < n; i++) 30 cin.getline(sbr[i], M); 31 double cnt = 0; 32 for(i = 0; i < n; i++) 33 { 34 mp.clear(); 35 int num = 0, ind = 0, ans = 0; 36 double tans = 0; 37 istringstream s(str[i]); // 利用库函数分离单词 38 istringstream b(sbr[i]); 39 string ss; 40 s >> ss; 41 while(s >> ss) 42 { 43 mp[ss] = 1; 44 num ++; 45 } 46 b >> ss; 47 while(b >> ss) 48 { 49 ans ++; 50 if(mp[ss]) 51 { 52 ind++; 53 tans += ind * 1.0 / (ans * 1.0); 54 } 55 } 56 cnt += (tans / (num * 1.0)); 57 } 58 printf("Case #%d: %.6lf\n",++cs,cnt / n); 59 } 60 return 0; 61 }