The 2013 ACM/ICPC Asia Changchun Regional Contest题解

47 篇文章 0 订阅
33 篇文章 2 订阅

A题水题,不多说

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 100005
#define eps 1e-8
#define INF 0x7FFFFFFF
typedef long long ll;

char s[1005];
int main(){
    int n,m,t,i;
    cin>>t;
    while(t--){
        cin>>n>>m;
        if(n>m){
            int tt = n;
            n = m;
            m = tt;
        }
        cin>>s;
        int k = 0;
        int l = strlen(s);
        for(i=0;i<n;i++){
            for(int j =0;j<m;j++){
                cout<<s[k++];
            }
            cout<<endl;
        }
    }
    return 0;
}

B题将一个十进制的正数装换成phi进制的数。一个模拟题,比赛中没有过。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 100005
#define eps 1e-8
#define INF 0x7FFFFFFF
#define ff sqrt(5.0)
typedef long long ll;
int main()
{
	int a[MAXN],n,bas=100;
	int flag;
	while(scanf("%d",&n)!=EOF)
	{
		memset(a,0,sizeof(a));
		a[50]=n;
		flag=1;
		while(flag)
		{
			flag=0;
			for(int i=2;i<100;i++)
			{
				if(a[i]>1)
				{
					a[i-2]+=a[i]/2;
					a[i+1]+=a[i]/2;
					a[i]%=2;
					flag=1;
				}
			}
			for(int i=0;i<100;i++)
			{
				if(a[i]&&a[i+1])
				{
					int tmp=min(a[i],a[i+1]);
					a[i+2]+=tmp;
					a[i]-=tmp;
					a[i+1]-=tmp;
					flag=1;
				}
			}
		}
		int st,ed;
		for(int i=100;i>=0;i--)
		{
			if(a[i])
			{
				st=i;
				break;
			}
		}
		for(int i=0;i<100;i++)
		{
			if(a[i])
			{
				ed=i;
				break;
			}
		}
		for(int i=st;i>=ed;i--)
		{
			if(i==49)
			{
				printf(".");
			}
			printf("%d",a[i]);
		}
		printf("\n");
	}
	return 0;
}


C题是人和猴子的智力竞赛,给出N个问题,每个问题有两个选项,做对可以获得相应的分数,猴子会随机选择一个答案也就是说猴子做对一道题得正确率是0.5,人希望不输给猴子的概率是p,求最少得到分数。

这道题是我读的,队友先想了一下2进制枚举的思路,然后卡了,我想到了DP求概率的方法,试了一发居然0ms过了,很少的0ms过题。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 100005
#define eps 1e-7
#define INF 0x7FFFFFFF
#define ff sqrt(5.0)
typedef long long ll;
double dp[44444];
int main()
{
	int t;
	int n;
	double p;
	int a[111];
	int sum;
	scanf("%d",&t);
	while(t--)
	{
		sum=0;
		memset(dp,0,sizeof(dp));
		scanf("%d%lf",&n,&p);
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		sort(a,a+n);
		dp[0]=1;
		for(int i=0;i<n;i++)
		{
			for(int j=sum;j>=0;j--)//从大的开始更新,不然会出现多乘一次0.5的错误
			{
				if(dp[j]!=0)
				{
					dp[j]*=0.5;
					dp[j+a[i]]+=dp[j];
				}
			}
			//cout<<dp[3]<<endl;
			sum+=a[i];
		}
		for(int i=0;i<=sum;i++)
		{
			if(dp[i]!=0)
			{
				//cout<<dp[i]<<endl;
			}
		}
		int ans=0;
		double s=0;
		for(int i=0;i<=sum;i++)
		{
			s+=dp[i];
			if(s>=p)
			{
				ans=i;
				break;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

I题要用hash表和map,代码暂时还没整理好,先贴OE大帝的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<cstdlib>
#include<queue>
#include<stack>
#include<vector>
#include<ctype.h>
#include<algorithm>
#include<string>
#define PI acos(-1.0)
#define maxn 10005
#define INF 0x7fffffff
#define SEED 31
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
map < ULL , int > P;
ULL Hash[100005];
ULL K[100005];
int main()
{
    int M,L;
    char ss[100005];
    while(scanf("%d%d",&M,&L)!=EOF)
    {
        ULL tt=1;
        scanf("%s",ss);
        int len=strlen(ss);
        ULL res=0;
        Hash[len]=0;
        K[0]=1;
        for(int i=1; i<=L; i++)
            K[i]=K[i-1]*SEED;
        for(int i=len-1; i>=0; i--)
        {
            Hash[i]=Hash[i+1]*SEED+(ss[i]-'a'+1);
        }
        int t=0,aa=0;
        for(int i=0; i<L&&i+M*L<len; i++)
        {
            P.clear();
            for(int j=i; j<M*L+i; j+=L)
            {
                P[Hash[j]-Hash[j+L]*K[L]]++;
            }
            if(P.size()==M)
                aa++;
            for(int j=M*L+i; j<=len-L; j+=L)
            {
                int head= j-M*L;
                P[Hash[head]-Hash[head+L]*K[L]]--;
                if(P[Hash[head]-Hash[head+L]*K[L]]==0)
                    P.erase(Hash[head]-Hash[head+L]*K[L]);
                P[Hash[j]-Hash[j+L]*K[L]]++;
                if(P.size()==M)
                    aa++;
            }
        }
        printf("%d\n",aa);
    }
    return 0;
}

E题,在琦神讲解后模仿琦神代码写了一发,吸收中

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iomanip>
#include <map>
#define maxn 1000
#define inf (1<<30)
#define PI acos(-1.0)
using namespace std;
const int N=362881;
typedef long long ll;
int ch,cv;
int fac[10];
struct node
{
	int x,w;
	node(int _x,int _w)
	{
		x=_x;
		w=_w;
	}
	bool operator <(const node &T)const 
	{
		return w>T.w;
	}
};
void Atoint(int *a,int &x)
{
	int y;
	x=0;
	for(int i=0;i<9;i++)
	{
		y=a[i];
		for(int j=0;j<i;j++)
		{
			if(a[j]<a[i])
			{
				y--;
			}
		}
		x+=fac[8-i]*y;
	}
}
void inttoA(int x,int *a)
{
	int has[10]={0};
	int i,j,y;
	for(i=0;i<9;i++)
	{
		y=x/fac[8-i];
		for(j=0;j<9;j++)
		{
			if(!has[j])
			{
				if(y==0)
				{
					break;
				}
				y--;
			}
		}
		a[i]=j;
		has[j]=1;
		x%=fac[8-i];
	}
}
int st,ed;
priority_queue<node> q;
int d[N],visit[N],a[10],b[10];
void update(int x,int w)
{
	if(!visit[x]&&d[x]>w)
	{
		d[x]=w;
		q.push(node(x,w));
	}
}
void work()
{
	Atoint(a,st);
	Atoint(b,ed);
	while(!q.empty())
	{
		q.pop();
	}
	memset(d,0x7F,sizeof(d));
	memset(visit,0,sizeof(visit));
	d[st]=0;
	q.push(node(st,0));
	int x,w,y;
	while(!q.empty())
	{
		x=q.top().x;
		w=q.top().w;
		q.pop();
		if(visit[x])
		{
			continue;
		}
		visit[x]=1;
		if(x==ed)
		{
			printf("%d\n",w);
			break;
		}
		inttoA(x,a);
		int i;
		for(i=0;i<9;i++)
		{
			if(!a[i])
			{
				break;
			}
		}
		 //cout<<i<<endl;
		swap(a[i],a[(i+1)%9]);
		Atoint(a,y);
		update(y,w+ch);
		swap(a[i],a[(i+1)%9]);
		swap(a[i],a[(i+8)%9]);
		Atoint(a,y);
		update(y,w+ch);
		swap(a[i],a[(i+8)%9]);
		swap(a[i],a[(i+3)%9]);
		Atoint(a,y);
		update(y,w+cv);
		swap(a[i],a[(i+3)%9]);
		swap(a[i],a[(i+6)%9]);
		Atoint(a,y);
		update(y,w+cv);
	}
}
int main()
{
	fac[0]=1;
	for(int i=1;i<10;i++)
	{
		fac[i]=fac[i-1]*i;
	}
	while(~scanf("%d%d",&ch,&cv))
	{
		if(ch==0&&cv==0)
		{
			break;
		}
		for(int i=0;i<9;i++)
		{
			scanf("%d",&a[i]);
		}
		for(int i=0;i<9;i++)
		{
			scanf("%d",&b[i]);
		}
		work();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值