zoukankan      html  css  js  c++  java
  • Codeforces Round #427 (Div. 2) [ C. Star sky ] [ D. Palindromic characteristics ] [ E. The penguin's game ]

    本来准备好好打一场的,然而无奈腹痛只能带星号参加 (我才不是怕被打爆呢!)

    PROBLEM C - Star sky

       OvO http://codeforces.com/contest/835/problem/C

      835C

      由于题目中给的c很小,可以对应每种亮度分别保存(c+1)个矩阵

      然后初始化一下求前缀矩阵

      每次询问就可以O(c)求出答案

    (Accepted)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    const int M=144;
    const int MM=100;
    
    int mp[M][M][20];
    int pre[M][M][20];
    int n,q,c;
    int ans;
    
    void init()
    {
    	int i,j,k;
    	memset(pre,0,sizeof(pre));
    	for(i=1;i<=MM;i++)
    		for(j=1;j<=MM;j++)
    			for(k=0;k<=c;k++)
    				pre[i][j][k]=pre[i-1][j][k]+pre[i][j-1][k]-pre[i-1][j-1][k]+mp[i][j][k];
    }
    
    int main()
    {
    	int chg,tmp,i,j,x,y,z,x1,y1,x2,y2,t;
    	cin>>n>>q>>c;
    	memset(mp,0,sizeof(mp));
    	for(i=1;i<=n;i++)
    	{
    		scanf("%d%d%d",&x,&y,&z);
    		mp[x][y][z]++;
    	}
    	init();
    	while(q--)
    	{
    		scanf("%d%d%d%d%d",&t,&x1,&y1,&x2,&y2);
    		ans=0;
    		for(i=0;i<=c;i++)
    		{
    			chg=(i+t)%(c+1);
    			tmp=pre[x2][y2][i]-pre[x1-1][y2][i]-pre[x2][y1-1][i]+pre[x1-1][y1-1][i];
    			ans+=tmp*chg;
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    

      

    PROBLEM D - Palindromic characteristics

      OWO http://codeforces.com/contest/835/problem/D

      835D

      对每两点做字符串哈希,然后搜索加记忆化(每搜索一段到一段合法的继续搜左右两边,递归,得到该段的类型,并且用类型来标记该段已经搜过)

      这样搜索的时间是O(n*n),然后O(1)判断哈希值是否相等,是的话就把对应计数值+1

      pretest能过,最后会不会挂掉就看我取的模了(趁终测还没结束赶紧睡觉~☆)(没挂嘿嘿嘿)

      

    (Accepted)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    typedef unsigned long long ull;
    
    const int M=5022;
    const int bas=14123;
    
    int ans[M];
    char s[M];
    int num[M];
    int n;
    unsigned hsh[M][M];
    int flag[M][M];
    
    void init()
    {
    	int i,j;
    	n=strlen(s+1);
    	for(i=1;i<=n;i++)
    	{
    		if(s[i]>='a')
    			num[i]=s[i]-'a';
    		else
    			num[i]=s[i]-'A'+26;
    	}
    	memset(ans,0,sizeof(ans));
    	memset(flag,-1,sizeof(flag));
    	for(i=1;i<=n;i++)
    	{
    		hsh[i][i]=num[i];
    		for(j=i+1;j<=n;j++)
    			hsh[i][j]=hsh[i][j-1]*bas+num[j];
    		for(j=i-1;j>=1;j--)
    			hsh[i][j]=hsh[i][j+1]*bas+num[j];
    	}
    }
    
    bool fj(int a,int b,int c,int d)
    {
    	return true;
    	int i,j;
    	for(i=a,j=d;i<=b;i++,j--)
    		if(num[i]!=num[j])
    			return false;
    	return true;	
    }
    
    int check(int a,int d)
    {
    	if(a==d) 
    	{
    		flag[a][d]=1;
    		return 1;
    	}
    	int tmp=(d-a+1)/2;
    	int b,c;
    	b=a+tmp-1; c=d-tmp+1;
    //	cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<hsh[a][b]<<' '<<hsh[d][c]<<endl;
    	if(hsh[a][b]==hsh[d][c] && fj(a,b,c,d))
    	{
    	
    		int flag0,flag1,flag2;
    
    		if(flag[a][b]!=-1) 
    			flag1=flag[a][b];
    		else
    		{
    			flag1=check(a,b);
    			flag[a][b]=flag1;
    			ans[flag1]++;
    		}
    			
    		if(flag[c][d]!=-1)
    			flag2=flag[c][d];
    		else
    		{
    			flag2=check(c,d);
    			flag[c][d]=flag2;
    			ans[flag2]++;
    		}
    		flag0=min(flag1,flag2);
    			return flag0+1;
    	}
    	else 
    	{
    		flag[a][d]=0;
    		return 0;
    	}
    }
    
    void solve()
    {
    	int i,j,a,b,c,d,len,tmp;
    	for(i=1;i<=n;i++)
    	{
    		for(j=i;2*j-i<=n;j++)
    		{
    			if(2*j-i<=n)
    			{
    				a=i; d=2*j-i; len=d-a+1;
    				if(flag[a][d]==-1)
    				{
    					tmp=check(a,d);
    					flag[a][d]=tmp;
    					ans[tmp]++;
    				}
    			}
    			if(2*j-i+1<=n)
    			{
    				a=i; d=2*j-i+1; len=d-a+1;
    				if(flag[a][d]==-1)
    				{					
    					tmp=check(a,d);
    					flag[a][d]=tmp;
    					ans[tmp]++;
    				}
    			}
    		}
    	}
    	for(i=n;i>=1;i--)
    		ans[i]+=ans[i+1];
    	for(i=1;i<=n;i++)
    	{
    		if(i-1) printf(" ");
    		printf("%d",ans[i]);
    	}
    	printf("
    ");
    }
    
    int main()
    {
    	int i,j;
    	scanf("%s",s+1);
    	init();
    	solve();
    	return 0;
    }
    

      

    一结束我就写了题解 怎么会有我这么勤奋的人呢 我真是太了不起了~☆

    PROBLEM E - The penguin's game

      OwO http://codeforces.com/contest/835/problem/E

      835E

      设要不同的2个点为p,q

      1. n的范围为1000,所以最多有10位。所以可以枚举每一位,对该为为1的数字输出,这样可以知道p,q哪些位数不同。(至多10次输出)

      2. p,q不同的位的数量至少为1。所以可以随便选取一位,然后,选出该位为1的数字,放入集合中,则这个集合中最多只有1个特殊点(设其为p),所以可以二分区间寻找改p(至多9次输出)

      3. 找到p点之后,根据第1步中得到的p和q中各位的关系,得到q

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    
    using namespace std;
    
    const int N=33;
    const int M=1111;
    
    int n,x,y;
    int dif[N],chs;
    int se[N][M],lse[N];
    int rep;
    
    void ask(int len,int s[])
    {
    	printf("? %d",len);
    	for(int i=1;i<=len;i++)
    		printf(" %d",s[i]);
    	printf("
    ");
    	fflush(stdout);
    	scanf("%d",&rep);
    }
    
    void output(int ans1,int ans2)
    {
    	printf("! %d %d
    ",ans1,ans2);
    	fflush(stdout);
    }
    
    void init()
    {
    	int i,j,mdl;
    	memset(lse,0,sizeof(lse));
    	for(i=1;i<=n;i++)
    	{
    		for(j=0;j<10;j++)
    		{
    			mdl=(1<<j);
    			if(i&mdl)
    				se[j][++lse[j]]=i;
    		}
    	}
    	chs=-1;
    	memset(dif,0,sizeof(dif));
    	for(i=0;i<10;i++)
    		if(lse[i]!=0)
    		{
    			ask(lse[i],se[i]);
    			if(rep!=0 && rep!=x)
    			{
    				dif[i]=1;
    				if(chs==-1)
    					chs=i;
    			}
    		}
    }
    
    void solve()
    {
    	int ans1,ans2;
    	int s[M],ls;
    	int i,j,tmp;
    	ls=0;
    	for(i=1;i<=n;i++)
    		if(i&(1<<chs))
    			s[++ls]=i;
    	int li,ri,mid;
    //	for(i=1;i<=ls;i++)
    //		cout<<s[i]<<' ';
    //	cout<<endl;
    	li=1; ri=ls;
    	while(li!=ri)
    	{
    		mid=(li+ri)>>1;
    		ask((mid-li+1),s+li-1);
    		if(rep==0 || rep==x)
    			li=mid+1;
    		else
    			ri=mid;
    	}
    	ans1=s[li];
    	ans2=ans1^(1<<chs);
    	for(i=0;i<10;i++)
    		if(i!=chs && dif[i]==1)
    			ans2^=(1<<i);
    	if(ans1>ans2) swap(ans1,ans2);
    	output(ans1,ans2);
    }
    
    int main()
    {
    	cin>>n>>x>>y;
    	init();
    	solve();
    	return 0;
    }
    

      

  • 相关阅读:
    CCF——分蛋糕(2017-3)
    CCF——公共钥匙盒(2017-9)
    CCF——打酱油(2017-9)
    CCF——游戏(2017-12)
    SDS-简单动态字符串
    Redis主从复制
    MySQL 知识点
    MySQL 死锁
    Java 类加载机制
    Java IO
  • 原文地址:https://www.cnblogs.com/FxxL/p/7266431.html
Copyright © 2011-2022 走看看