【NOIP2011】提高组

Day1

T1铺地毯

题目链接

O(n)扫一遍,嗯,没了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 struct node{
 5     int x,y,px,py;
 6 }e[10005];
 7 int read(){
 8     int ans=0,f=1;char c=getchar();
 9     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
10     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
11     return ans*f; 
12 }
13 int main(){
14     int n=read();
15     for(int i=1,a,b,c,d;i<=n;i++){
16         a=read();b=read();c=read();d=read();
17         e[i]=(node){a,b,c,d};
18     }
19     int x=read(),y=read();
20     int id=-1;
21     for(int i=1;i<=n;i++){
22         node p=e[i];
23         if(x>=p.x&&x<=p.x+p.px&&y>=p.y&&y<=p.y+p.py)id=i;
24     }
25     printf("%d",id);
26     return 0;
27 }
D1 T1

T2选择客栈

题目链接

理解错题意WA了好几发......

题目要求的是满足col[x]==col[y]且[x,y]间存在money[i]<=p的对数

接下来就很简单了,sum[i]表示i这种色调出现了几次,last[i]表示i这种色调最后一次出现的位置,xtd[k]表示前k个客栈中money[i]<=p的数量。

那么当xtd[i]-xtd[last[i]]-1>0时,当前客栈可与前面任何同色调的客栈配对,f[i]=sum[col[i]]。

否则,f[i]=f[last[i]]。

每次求个和就好了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include <algorithm>
 4 const int N=2e5+10;
 5 int mon[N],pi[N];
 6 int read(){
 7     int ans=0,f=1;char c=getchar();
 8     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 9     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
10     return ans*f;
11 }
12 int ans=0,f[N],xtd[N],sum[55];
13 int last[55];
14 int main(){
15     int n=read();read();int p=read();
16     for(int i=1;i<=n;i++){
17         pi[i]=read();mon[i]=read();
18         if(!last[pi[i]])last[pi[i]]=i;
19     }
20     for(int j=1;j<=n;j++){
21         xtd[j]=xtd[j-1];
22         if(mon[j]<=p)xtd[j]++;
23         sum[pi[j]]++;
24         if(j==last[pi[j]])continue;
25         if(xtd[j]-xtd[last[pi[j]]-1])f[j]=sum[pi[j]]-1;
26         else f[j]=f[last[pi[j]]];
27         ans+=f[j];
28         last[pi[j]]=j;
29     }
30     printf("%d",ans);
31     return 0;
32 }
D1 T2

T3Mayan游戏

题目链接

爆搜题......先弃坑,有空再补(tan90度)。

 


 

Day2

T1计算系数

题目链接

数学题,很容易得到答案就是an*bm*C(k,n)-->不会去问数学老师->v->

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 typedef long long LL;
 5 const int mod=1e4+7;
 6 int a,b,k,n,m;
 7 int ksm(LL a,int b){
 8     int res=1;
 9     while(b){
10         if(b&1)res=res*a%mod;
11         a=a*a%mod;
12         b>>=1;
13     }
14     return res;
15 }
16 LL C(int x,int y){
17     LL res=x;
18     for(int i=2;i<=y;i++){
19         res=res*(x-i+1)%mod*ksm(i,mod-2)%mod;
20     }
21     return res;
22 }
23 int main(){
24     scanf("%d %d %d %d %d",&a,&b,&k,&n,&m);
25     LL ans=1;
26     ans=ans*ksm(a,n)%mod*ksm(b,m)%mod;
27     ans=ans*C(k,n)%mod;
28     printf("%lld",ans);
29     return 0;
30 }
D2 T1

T2聪明的质检员

题目链接

二分一个W,在二分的过程中不断取极差的min就好了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 typedef long long LL;
 5 const int N=2e5+10;
 6 int n,m,wi[N],vi[N],li[N],ri[N];
 7 LL s,qian[N];
 8 int sum[N];
 9 LL read(){
10     LL ans=0,f=1;char c=getchar();
11     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
12     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
13     return ans*f;
14 }
15 LL abs(LL a){return a>0?a:-a;}
16 LL ans;
17 bool check(LL x){
18     LL ss=0;
19     for(int i=1;i<=m;i++){
20         int l=li[i],r=ri[i];
21         LL w=qian[r]-qian[l-1];
22         int num=sum[r]-sum[l-1];
23         ss+=w*num;
24     }
25     ans=std::min(ans,abs(ss-s));
26     return ss<s;
27 }
28 LL l=0,r=0;
29 int main(){
30     n=read();m=read();s=read();
31     for(int i=1;i<=n;i++)wi[i]=read(),vi[i]=read(),r=std::max(r,(LL)wi[i]);
32     for(int i=1;i<=m;i++)li[i]=read(),ri[i]=read();
33     ans=1e18;r++;
34     while(l<r){
35         LL mid=(l+r)>>1;
36         qian[0]=0;sum[0]=0;
37         for(int i=1;i<=n;i++){
38             qian[i]=qian[i-1];
39             sum[i]=sum[i-1];
40             if(wi[i]>=mid)qian[i]+=vi[i],sum[i]++;
41         }
42         if(check(mid))r=mid;
43             else l=mid+1;
44     }
45     printf("%lld",ans);
46     return 0;
47 }
D2 T2

T3观光公交

题目链接

每次使用加速器的效果只有到出现车等人的情况才会结束,中间的乘客都可以享受到加速的待遇。

那么我们只要贪心地每次取出一段人数最多的使用加速器就好啦。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 const int N=1005,M=1e4+10;
 5 int n,m,k;
 6 int read(){
 7     int ans=0,f=1;char c=getchar();
 8     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 9     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
10     return ans*f;
11 }
12 int tim[N],l[M],fr[M],to[M],arr[N],down[N];
13 int go[N];
14 int ans=0,mxa=0;
15 void init(){
16     for(int i=1;i<=n;i++)arr[i]=std::max(arr[i-1],go[i-1])+tim[i-1];
17 }
18 int main(){
19     n=read();m=read();k=read();
20     for(int i=1;i<n;i++)tim[i]=read();
21     for(int i=1;i<=m;i++){
22         l[i]=read();fr[i]=read();to[i]=read();
23         down[to[i]]++;
24         go[fr[i]]=std::max(go[fr[i]],l[i]);
25     }
26     init();
27     for(int i=1;i<=m;i++)ans+=arr[to[i]]-l[i];
28     while(k){
29         int x=0,sum[N];
30         memset(sum,0,sizeof(sum));
31         for(int i=n;i>1;i--){
32             if(tim[i-1]){
33                 sum[i-1]=down[i];
34                 if(arr[i]>go[i])sum[i-1]+=sum[i];
35             }
36         }
37         for(int i=1;i<=n;i++)
38             if(sum[i]>sum[x])x=i;
39         if(!x)break;
40         tim[x]--;k--;
41         ans-=sum[x];
42         init();
43     }
44     printf("%d\n",ans);
45     return 0;
46 }
D3 T3

 

posted @ 2017-11-05 21:30  Child-Single  阅读(300)  评论(0编辑  收藏  举报