多校联合 (3)

题目: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中 

View Code
 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,后来发现少考虑了一些情况,今天看了一下标程,原来它是求的最短不同序列

View Code
 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  

View Code
 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,一样的题目。线段树染色询问的一种变形,数据给的需要离散化,其他的也没什么。不过可能是数据问题,用树状数组不进行离散化也是可以的

View Code
 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 }

标程是先对输入的时间点和询问点进行离散化后,只保留那些没有重复的数值,然后建树,插入,询问

View Code
  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 即为结果。现在题意已经说完。题目一点不难,稍带着字符串的处理,但就纠结在了读题上,怎么都绕不过来题目的意思。

深感库函数的强大和便利

View Code
 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 }

 

 

posted @ 2012-08-01 21:48  AC_Girl  阅读(203)  评论(0编辑  收藏  举报