AmazingCounters.com

BestCoder Round #32

问题描述
目前,我们用PM2.5的含量来描述空气质量的好坏。一个城市的PM2.5含量越低,它的空气质量就越好。所以我们经常按照PM2.5的含量从小到大对城市排序。一些时候某个城市的排名可能上升,但是他的PM2.5的含量也上升了。这就意味着他的空气质量并没有改善。所以这样的排序方式是不合理的。为了使得排序合理,我们提出了一个新的排序方法。我们按照两个PM2.5含量测量的差值(第一次-第二次)来对他们按降序排序,如果有重复,按照第二次的测量值升序排序,如果还有重复,按照输入的顺序排序。
输入描述
多组测试数据(大概100组),每一组测试数据第一行先给出一个整数n,代表有n个城市需要被排序。城市被从0n1标号。接下来n行,每一含有两个整数代表每一个城市第一次和第二次被测量的PM2.5值。第i行描述城市i1的信息。
请处理到文件末尾。
[参数说明]
所有整数都在[1,100]的范围内。
输出描述
对于每一个数据,输出排好序之后的城市ID。
输入样例
2
100 1
1 2
3
100 50
3 4
1 2
输出样例
0 1
0 2 1

思路:三关键词排序

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define maxn 1000
 5 char ch[maxn];
 6 using namespace std;
 7 struct T
 8 {
 9     int x;int y;int z;
10 }a[maxn];
11 int cmp(T x,T y)
12 {
13     return ((x.x>y.x) ||((x.x==y.x && (x.y<y.y))) || (x.x==y.x && x.y==y.y && (x.z<y.z)));
14 }
15 int main()
16 {
17     int n,x,y;
18     while(scanf("%d",&n)!=EOF)
19     {
20         for(int i=1;i<=n;i++)
21         {
22             scanf("%d%d",&x,&y);
23             a[i].x=x-y;
24             a[i].y=y;
25             a[i].z=i-1;
26         }
27         sort(a+1,a+1+n,cmp);
28         for(int i=1;i<n;i++)
29         {
30             printf("%d ",a[i].z);
31         }
32         printf("%d\n",a[n].z);
33     }
34     return 0;
35 }
View Code
问题描述
给定一个数组(a0,a1,a2,an1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0ij<n)使得 NPsum(i,j) 刚好为K。这里NPsum(i,j)=aiai+1+ai+2++(1)jiaj
输入描述
多组测试数据。在文件的第一行给出一个T,表示有T组数据。
在接下来的2T行里,将会给出每一组数据。
每一组数据占两行,第一行包含nK。
第二行包含(a0,a1,a2,an1)以一个空格分开。
[参数说明]
所有输入均为整数。
0<T25,1n1000000,1000000000ai1000000000,1000000000K1000000000
输出描述
对于每一个数据,输出占一行,输出格式是Case #id: ans,这儿id是数据编号,从1开始,ans是根据是否找到满足的二元组而定为“Yes.” 或 “No.” (不包含引号)
看样例可以获得更多的信息。
输入样例
2
1 1
1
2 1
-1 0
输出样例
Case #1: Yes.
Case #2: No.
Hint
如果数据比较多,建议使用快速读入

思路: 比赛的时候认为这个规模带log的都会卡,不然直接map了,然后学了种挂链表的神奇的HASH

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define maxn 1000009
 5 #define MOD 10000009
 6 using namespace std;
 7 int head[MOD+10],nex[maxn],a[maxn];
 8 long long point[maxn],now=0,sum[maxn];
 9 long long n,k;
10 int add(int x,int y)
11 {
12     nex[++now]=head[x];
13     head[x]=now;
14     point[now]=y;
15 }
16 void insert(long long x)
17 {
18     long long u=x%MOD;if(u<0)u*=-1;
19     for(int i=head[u];i;i=nex[i])
20     {
21         if(point[i]==x)return;
22     }
23     add(u,x);
24 }
25 int find(long long x)
26 {
27     long long u=x%MOD;if(u<0)u*=-1;
28     for(int i=head[u];i;i=nex[i])
29     {
30         if(point[i]==x)return 1;
31     }
32     return 0;
33 }
34 long long read()
35 {
36     long long x=0,f=1;char ch=getchar();
37     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
38     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
39     return x*f;
40 }
41 int main()
42 {
43     int t,cas=0;
44     t=read();
45     while(t--)
46     {
47         n=read();k=read();
48         for(int i=1;i<=n;i++)a[n-i+1]=read();
49         for(int i=1;i<=n;i++)
50         {
51             if(i&1)
52             {
53                 sum[i]=sum[i-1]+a[i];
54             }else sum[i]=sum[i-1]-a[i];
55         }    
56         int flag=0;
57         insert(0);
58         for(int i=1;i<=n;i++)
59         {
60             if(i&1)
61             {
62                 if(find(sum[i]-k)){flag=1;break;}
63             }
64             else if(find(sum[i]+k)){flag=1;break;}
65             insert(sum[i]);
66         }
67         printf("Case #%d: ",++cas);
68         if(flag)printf("Yes.\n");
69         else printf("No.\n");
70         memset(head,0,sizeof(head));
71         now=0;
72     }
73     return 0;
74 }
View Code

 

 

HDU 5184 Brackets

问题描述
我们给出下列递归的合法括号序列的定义:
  ● 空序列是合法括号序列
  ● 如果s是一个合法括号序列,那么(s)也是合法括号序列
  ● 如果a和b是合法括号序列,那么ab也是合法括号序列
  ● 没有其它情况是合法括号序列

比如下列括号序列是合法括号序列
(), (()), ()(), ()(())
下列括号序列则不是
(, ), )(, ((), ((()

现在,我们要构造长度为n的合法括号序列,前面的一些括号已经给出,问可以构造出多少合法序列。
输入描述
多组测试数据(大概2000),每一组数据占两行。
第一行给出一个整数n。
第二行给出一个字符串代表前面已经确定的几个括号。
请处理到文件末尾。

[参数约定]
1n1000000
字符串只包含’(’和’)’,长度大于0并且不超过n.
输出描述
对于每一个数据,在一行中输出答案对1000000007取余的结果。
输入样例
4
()
4
(
6
()
输出样例
1
2
2
Hint
第一组数据只有一种可能,它就是()().
对于第二组数据他有两种可能,他们是(()) 和()().
对于第三种数据,两种可能是()()() 和()(()).

 

思路:这题建模有点醉啊 问题可以变成,从(0,0)到(n/2-a,n/2-b)且不越过y=x 这条线的方案数,然后从(0,0)到(p,q)且不经过y=x的方案数是C(p,p+q)-C(p-1,p+q)

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define MOD 1000000007
 5 #define LLD "%lld"
 6 #define maxn 1000009
 7 #define ll long long
 8 using namespace std;
 9 char ch[maxn];
10 ll fac[maxn],inv[maxn];
11 ll qpow(ll a,ll n)
12 {
13     ll ret=1;
14     for(;n;n>>=1)
15     {
16         if(n&1)ret=(ret*a)%MOD;
17         a=(a*a)%MOD;
18     }
19     return ret;
20 }
21 ll C(ll n,ll m)
22 {
23         if(m==0)return 1;
24         ll u=fac[n],v = inv[n-m],w=inv[m];
25     return (((fac[n]*inv[n-m])%MOD)*inv[m])%MOD;
26 }
27 int main()
28 {
29     ll n;
30     fac[0]=1;
31     for(int i=1;i<=maxn-1;i++)
32     {
33         fac[i]=(fac[i-1]*(long long)i)%MOD;
34         inv[i]=qpow(fac[i],MOD-2)%MOD;
35     }
36     while(scanf( LLD "%s",&n,ch+1)!=EOF)
37     {
38         if(n&1)
39         {
40             puts("0");
41             continue;
42         }
43         ll len=strlen(ch+1);
44         ll lef=0,flag=0,a=0,b=0;
45         for(int i=1;i<=len;i++)
46         {
47             if(ch[i]=='(')a++;else b++;
48             if(ch[i]=='(')lef++;
49             else if(lef!=0)lef--;
50             else flag=1;
51         }
52         if(flag){puts("0");continue;}
53         
54         ll p=( n >> 1 ) - a,q= ( n >> 1 ) - b;
55         if(p<0 ||q<0){puts("0");continue;}
56         if(p>q)swap(p,q);
57         ll u =  C(p + q , p), v = C(p + q ,p - 1);
58         printf(LLD "\n" , (C(p + q , p) - C(p + q,p - 1) + MOD ) % MOD);
59     }
60     return 0;
61 }
View Code

 

posted @ 2015-03-08 14:27  philippica  阅读(192)  评论(0编辑  收藏  举报