AmazingCounters.com

2013   Dhaka 区域赛

A.uva 12709 Falling ANTS

首先按照H排序,然后按照L*H*W排序 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <math.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 #define maxn 100009
 7 #define inf 100000
 8 using namespace std;
 9 int main()
10 {
11         int n,a,b,c;
12         while(1)
13         {
14                 int ans=0,ans_h=0;
15                 scanf("%d",&n);
16                 if(n==0)break;
17                 for(int i=1;i<=n;i++)
18                 {
19                         scanf("%d%d%d",&a,&b,&c);
20                         if(c>ans_h)ans_h=c,ans=a*b*c;
21                         else if(c==ans_h && a*b*c>ans)ans=a*b*c;
22                 }
23                 printf("%d\n",ans);
24         }
25         return 0;
26 }
View Code

 D uva 12712 Pattern Locker

题目大意:一个L*L的安卓密码锁,问最少按M个钮,最多按N个扭,一共有多少中不同的方式加锁,注意正常来说1 3 2,是不合法的,但在这里是合法的,但同一个按钮还是不能走两次

思路:排列组合一下就出来了,比如第一个样例:9*8*7*6+9*8*7*6*5+9*8*7*6*5*4+9*8*7*6*5*4*3+9*8*7*6*5*4*3*2+9*8*7*6*5*4*3*2*1

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <math.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 #define maxn 100009
 7 #define inf 100000
 8 #define MOD (10000000000007ll)
 9 using namespace std;
10 int main()
11 {
12         int t,cas=0;
13         scanf("%d",&t);
14         while(t--)
15         {
16                 long long a,b,c;
17                 scanf("%lld%lld%lld",&a,&b,&c);
18                 long long u=a*a,ans=1;
19                 for(int i=1;i<=b;i++)ans=ans*(u-i+1)%MOD;
20                 long long temp=ans;
21                 for(int i=b+1;i<=c;i++)
22                         temp=(temp*(u-i+1))%MOD,ans=(ans+temp%MOD)%MOD;
23                 printf("Case %d: %lld\n",++cas,ans);
24         }
25         return 0;
26 }
View Code

E uva 12713 Pearl Chains

题目大意:有三种类型的珍珠,每种类型的珍珠分别能够染色x,y,z种颜色,1号类型珍珠加3号类型珍珠共A个,2号类型珍珠和3号类型珍珠共B个,问有多少种摆珍珠的方案

思路:公式在比赛的时候就推出来了,枚举2号类型的珍珠个数即可 ΣC(i,A+B-i)*C(A-i,A+B-2*i)*xA-1*yB-1*zi,关键数字太大,还需要lucas定理

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <math.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 #include<queue>
 7 #define MOD 1000003
 8 #define maxn 1000000
 9 using namespace std;
10 long long fac[MOD+10],inv[MOD+10],a,b,x,y,z;
11 long long mpow(long long a,long long n){
12         if(n==0)return 1;
13         if(n==1)return a%MOD;
14         if(n&1)return (a*mpow(a,n-1))%MOD;
15         else{
16                 long long u=mpow(a,n>>1);
17                 return (u*u)%MOD;
18         }
19 }
20 long long C(long long m,long long n)
21 {
22         if(m==0)return 1;
23         return ((fac[n]*inv[m]%MOD)*inv[n-m])%MOD;
24 }
25 int main()
26 {
27         int t;
28         fac[0]=inv[0]=1;
29         for(int i=1;i<=MOD;i++)
30         {
31                 fac[i]=(fac[i-1]*(long long)i)%MOD;
32                 inv[i]=mpow(fac[i],MOD-2);
33                // cout << fac[i]<<" "<<inv[i]<<endl;
34         }
35         scanf("%d",&t);
36         //printf("%lld\n",C(2,5));
37         while (t--)
38         {
39                 long long ans=1;
40                 scanf("%lld%lld%lld%lld%lld",&a,&b,&x,&y,&z);
41                 x%=MOD;y%=MOD;z%=MOD;
42                 while(a||b)
43                 {
44                         long long u=a%MOD,v=b%MOD,min_x=min(u,v),ret=0,temp=1;
45                         for(int i=0;i<=min_x;i++)
46                         {
47                                 temp=(C(i,u+v-i)*C(u-i,u+v-i-i))%MOD;
48                                 temp=(temp*mpow(x,u-i))%MOD;
49                                 temp=(temp*mpow(y,v-i))%MOD;
50                                 temp=(temp*mpow(z,i))%MOD;
51                                 ret=(ret+temp)%MOD;
52                         }
53                         ans=(ans*ret)%MOD;
54                         a/=MOD,b/=MOD;
55                 }
56                 printf("%lld\n",ans);
57         }
58         return 0;
59 }
View Code

 

 

F uva 12714 Two Points Revisited

题目大意:给你两个点,要你再求两点,使得与题目中给出的两点垂直,并且两点要在矩形框内,输出任意一种即可

思路:思路很多,CP和zyx分别有自己的思路,其实就是个sb题,我的话先求出任意一条垂直的两点,然后将其平移到第一象限,然后再将其移到第一象限的左下角即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <math.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 #define maxn 100009
 7 #define inf 100000
 8 #define MOD (10000000000007ll)
 9 using namespace std;
10 int main()
11 {
12         int t,cas=0,x1,y1,x2,y2,x3,x4,y3,y4;
13         scanf("%d",&t);
14         while(t--)
15         {
16                 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
17                 x3=x1,y3=y1,x4=x1+y2-y1,y4=y1-(x2-x1);
18                 if(x3<0)x4-=x3,x3=0;
19                 if(y3<0)y4-=y3,y3=0;
20                 if(x4<0)x3-=x4,x4=0;
21                 if(y4<0)y3-=y4,y4=0;
22                 int u=min(y4,y3);
23                 y4-=u,y3-=u;
24                 u=min(x4,x3);
25                 x4-=u;x3-=u;
26                 printf("Case %d: %d %d %d %d\n",++cas,x3,y3,x4,y4);
27         }
28         return 0;
29 }
View Code

H UVA 12716 GCD XOR

题目大意:有多少小于等于N的数对(A,B),满足GCD(A,B)=A XOR B 1<=B<=A<=N

思路:感觉能想出这题真心好不容易!!!关键要知道一个结论:设GCD(A,B)= C ,A-C=B

以上结论在打过N张表后被总结下来,其中ZYX在这道题几乎耗了3个多小时TUT,知道结论以后暴力即可!

然后照着结论推证明

A-B<=A XOR B<=A+B  (由于XOR可以理解成不带进位的加法,同样也可以理解成不带借位的减法)

∵A XOR B=GCD(A,B)

∴A-B<=GCD(A,B)<=A+B

同时由辗转相减法可得GCD(A,B)=GCD(A-B,B)<=A-B

即A-B<=GCD(A,B)<=A-B

QED.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <math.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 #include<queue>
 7 #define maxn 30000000
 8 #define inf 100000
 9 #define MOD (10000000000007ll)
10 using namespace std;
11 int ans[maxn];
12 int main()
13 {
14         for(int i=1;i<=maxn;i++)
15                 for(int j=2;j*i<=maxn;j++)
16                 {
17                         int u=i*j,b=u-i;
18                         if((b^u)==i)ans[u]++;
19                 }
20         for(int i=2;i<=maxn;i++)ans[i]+=ans[i-1];
21         int t,n,cas=0;
22         scanf("%d",&t);
23         while(t--)
24         {
25                 scanf("%d",&n);
26                 printf("Case %d: %d\n",++cas,ans[n]);
27         }
28         return 0;
29 }
View Code

 

I UVA 12717 Fiasco

题目大意:前面给了一坨眼睛都快看出血的代码,其实是prim,所以它做的应该是求出以s为根的最小生成树,而要最小生成树上的边正好等于最短路树

思路:这题的话DFS序和BFS序应该都行,一开始看样例构造了个BFS序就过了,证明的话以DFS序为例子,假设现在正在遍历非树边,那它的序号一定比所有的树边大,并且当前构成环,由MST回路性质可得该边肯定不是MST上的边,很明显该边也肯定不是最短路树上的边

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <math.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 #include<queue>
 7 #define maxn 250000
 8 #define inf 100000
 9 #define MOD (10000000000007ll)
10 using namespace std;
11 int cnt=0;
12 int head[maxn],next[maxn],point[maxn],now=1;
13 int ans[maxn],n,m,source,x[maxn],y[maxn],v[maxn];
14 bool visit[maxn],visit1[maxn];
15 void add(int x,int y,int v)
16 {
17         next[++now]=head[x];
18         head[x]=now;
19         point[now]=y;
20 }
21 void bfs(int s)
22 {
23         queue<int>q;
24         q.push(s);
25         visit[s]=1;
26         while(!q.empty())
27         {
28                 s=q.front();
29                 q.pop();
30                 for(int i=head[s];i;i=next[i])if(!visit1[i])
31                 {
32                         visit1[i]=visit1[i^1]=1;
33                         int u=point[i];
34                         ans[i>>1]=++cnt;
35                         if(!visit[u])q.push(u),visit[u]=1;
36                 }
37         }
38 }
39 int main()
40 {
41         int t,cas=0;
42         scanf("%d",&t);
43         while(t--)
44         {
45                 now=1; cnt=0;
46                 memset(visit,0,sizeof(visit));
47                 memset(visit1,0,sizeof(visit1));
48                 memset(head,0,sizeof(head));
49                 scanf("%d%d%d",&n,&m,&source);
50                 printf("Case %d:\n",++cas);
51                 for(int i=1;i<=m;i++)
52                 {
53                         scanf("%d%d%d",&x[i],&y[i],&v[i]);
54                         add(x[i],y[i],v[i]);
55                         add(y[i],x[i],v[i]);
56                 }
57                 bfs(source);
58                 //printf("%d\n",cnt);
59                 for(int i=1;i<=m;i++)
60                 {
61                         printf("%d %d %d\n",x[i],y[i],ans[i]);
62                 }
63         }
64         return 0;
65 }
View Code

 

J  uva 12718 Dromicpalin Substrings

题目大意:一个字符串,有多少连续的子串可以重排成回文串

思路:显然能够重排成回文串的字符串奇数个字符的个数小于等于1,然后O(n^2)扫一遍就行

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <math.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 #define maxn 100009
 7 #define inf 100000
 8 #define MOD (10000000000007ll)
 9 using namespace std;
10 char ch[maxn];
11 int visit[30];
12 int main()
13 {
14         int t,cas=0;
15         scanf("%d",&t);
16         while(t--)
17         {
18                 int ans=0,odd;
19                 scanf("%s",ch+1);
20                 int len=strlen(ch+1);
21                 for(int i=1;i<=len;i++)
22                 {
23                         memset(visit,0,sizeof(visit));
24                         for(int j=i;j>=1;j--)
25                         {
26                                 if(i==j)
27                                 {
28                                         visit[ch[i]-'a']=1;
29                                         odd=1;
30                                         ans++;
31                                 }
32                                 else
33                                 {
34                                         visit[ch[j]-'a']=visit[ch[j]-'a']+1;
35                                         if(visit[ch[j]-'a']&1)odd++;
36                                         else odd--;
37                                         if(odd<=1)ans++;
38                                 }
39                         }
40                 }
41                 printf("Case %d: %d\n",++cas,ans);
42         }
43         return 0;
44 }
View Code

 

posted @ 2015-02-04 15:43  philippica  阅读(316)  评论(1编辑  收藏  举报