2012 Multi-University Training Contest 1

慢慢写,慢慢更新~

A.Clairewd’s message 模拟~

#include<cstdio>
#include<cstring>
#include<map>
using namespace std;

map <char,char> p;
char s[200001];

int main()
{
	int T,len,i,j,k;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%s",s);
		len=strlen(s);
		for(i=0;i<len;i++)
			p[s[i]]='a'+i;
		scanf("%s",s);
		len=strlen(s);
		for(i=(len+1)/2;i<=len;i++)
		{
			for(j=0;j<i;j++)
				if((p[s[j]]!=s[j+i])||(j+i>=len)) break;
			if((p[s[j]]==s[j+i])||(j+i>=len))
			{
				for(k=0;k<i;k++)
					printf("%c",s[k]);
				for(k=0;k<i;k++)
					printf("%c",p[s[k]]);
				printf("\n");
				break;
			}
		}
	}
	return 0;
}						

 

B.Divide Chocolate

   给你一块2*n的巧克力,让你分成k块,问有多少种分发。 递推,公式很简单。用0和1表示前面一列是否分为两个部分。

#include<iostream>
#include<cstring>
using namespace std;

const int N=1001;
const int K=2002;
const int MOD=100000007;

__int64 f[N][K][2];

int main()
{
    memset(f,0,sizeof(f));
    f[1][1][0]=1;
    f[1][2][1]=1;
    for(int i=2;i<=1000;++i)
    {
        for(int j=1;j<=2000;++j)
        {
            f[i][j][0]=f[i-1][j][0]+f[i-1][j-1][0]+f[i-1][j][1]*2+f[i-1][j-1][1];
            f[i][j][1]=f[i-1][j-1][1]*2+f[i-1][j][1]+f[i-1][j-1][0]*2;
            if(j>1)
            {
                f[i][j][1]+=f[i-1][j-2][0]+f[i-1][j-2][1];
            }
            f[i][j][0]%=MOD;
            f[i][j][1]%=MOD;
        }
    }
    int T,n,k;
    cin>>T;
    while(T--)
    {
        cin>>n>>k;
        cout<<(f[n][k][0]+f[n][k][1])%MOD<<endl;
    }
    return 0;
}

 

 

C.Holedox Eating 

一只呆在管道里的小动物吃蛋糕,管道可以看做一个坐标轴,小动物一开始在0位置。现在有n个事件,【0 x】表示在x位置出现一个蛋糕,【1】表示现在小动物想吃蛋糕了。每个时刻,如果它想吃蛋糕,那么遵循这样一个规律:如果管道中当前不存在蛋糕,那么它原地不动。如果存在蛋糕,那么寻找离自己最近的一个,爬过去吃掉。如果存在两个蛋糕离自己一样近(一左一右),那么按照前一个时刻爬行的方向爬行吃掉那个蛋糕。

线段树ok,multiset更简单~

#include<iostream>
#include<cstdio>
#include<set>
using namespace std;

const int MAX=1000000;
const int MIN=-1000000;

int main()
{
	int i,T,n,l,x,now,ans,len1,len2,flag;
	multiset <int> aa;
	multiset <int>::iterator itl,itr;
	scanf("%d",&T);
	i=0;
	while(T--)
	{
		now=ans=0;
		flag=1;            //表示方向向右
		i++;                
		aa.clear();
		aa.insert(MAX);
		aa.insert(MIN);
		scanf("%d%d",&l,&n);
		while(n--)
		{
			scanf("%d",&x);
			if(!x)
			{
				scanf("%d",&x);
				aa.insert(x);
			}
			else
			{
				itl=itr=aa.lower_bound(now);
				if(*itr==now)
				{
					aa.erase(itr);
					continue;
				}
				itl--;
				if(aa.size()==2) continue;
				len1=now-*itl;
				len2=*itr-now;
				if(len1==len2)
				{
					if(flag) 
					{
						aa.erase(itr);
						now=*itr;
					}
					else 
					{
						aa.erase(itl);
						now=*itl;
					}
					ans+=len1;
					continue;
				}
				if(len1<len2)
				{
					aa.erase(itl);
					now=*itl;
					flag=0;
					ans+=len1;
					continue;
				}
				if(len2<len1)
				{
					aa.erase(itr);
					now=*itr;
					flag=1;
					ans+=len2;
					continue;
				}
			}
		}
		printf("Case %d: %d\n",i,ans);
	}
	return 0;
}

 

 

 

 

D.Hourai Jeweled

tree dp

 

E.Let's Hit Our Head!

实在是....读不懂题

 

F.Lightning

生成树计数吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值