BestCoder Round #32
问题描述
目前,我们用PM2.5的含量来描述空气质量的好坏。一个城市的PM2.5含量越低,它的空气质量就越好。所以我们经常按照PM2.5的含量从小到大对城市排序。一些时候某个城市的排名可能上升,但是他的PM2.5的含量也上升了。这就意味着他的空气质量并没有改善。所以这样的排序方式是不合理的。为了使得排序合理,我们提出了一个新的排序方法。我们按照两个PM2.5含量测量的差值(第一次-第二次)来对他们按降序排序,如果有重复,按照第二次的测量值升序排序,如果还有重复,按照输入的顺序排序。
输入描述
多组测试数据(大概100组),每一组测试数据第一行先给出一个整数n,代表有n个城市需要被排序。城市被从0到n−1标号。接下来n行,每一含有两个整数代表每一个城市第一次和第二次被测量的PM2.5值。第i行描述城市i−1的信息。
请处理到文件末尾。
[参数说明]
所有整数都在[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 }
问题描述
给定一个数组(a0,a1,a2,⋯an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP−sum(i,j) 刚好为K。这里NP−sum(i,j)=ai−ai+1+ai+2+⋯+(−1)j−iaj。
输入描述
多组测试数据。在文件的第一行给出一个T,表示有T组数据。
在接下来的2∗T行里,将会给出每一组数据。
每一组数据占两行,第一行包含n和K。
第二行包含(a0,a1,a2,⋯an−1)以一个空格分开。
[参数说明]
所有输入均为整数。
0<T≤25,1≤n≤1000000,−1000000000≤ai≤1000000000,−1000000000≤K≤1000000000
输出描述
对于每一个数据,输出占一行,输出格式是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 }
HDU 5184 Brackets
问题描述
我们给出下列递归的合法括号序列的定义:
● 空序列是合法括号序列
● 如果s是一个合法括号序列,那么(s)也是合法括号序列
● 如果a和b是合法括号序列,那么ab也是合法括号序列
● 没有其它情况是合法括号序列
比如下列括号序列是合法括号序列
(), (()), ()(), ()(())
下列括号序列则不是
(, ), )(, ((), ((()
现在,我们要构造长度为n的合法括号序列,前面的一些括号已经给出,问可以构造出多少合法序列。
输入描述
多组测试数据(大概2000),每一组数据占两行。
第一行给出一个整数n。
第二行给出一个字符串代表前面已经确定的几个括号。
请处理到文件末尾。
[参数约定]
1≤n≤1000000
字符串只包含’(’和’)’,长度大于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 }