14届zufe校赛热身赛

7 篇文章 0 订阅

Problem B: Matrix Fast Power

题意:

Jelly has a sequence A, A1 = X, A2 = Y, when i 3, Ai = F(Ai1)+F(Ai2).
Where
F(x) represents the sum of the digits of x. For example, F(283) = 2 + 8 + 3 = 13.Now, give you three integers X, Y and N, please calculate AN



POINT:

很简单,找循环节。

可是训练赛中却写超时了。


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define LL long long
LL f(LL x)
{
    LL sum=0;
    while(x){
        sum+=x%10;
        x=x/10;
    }
    return sum;
}
 
void d(LL &x,LL &y)
{
    LL t=x;
    x=y;
    y=f(t)+f(y);
}
LL mp[33][33];
LL flag[33][33];
void dfs(LL x,LL y,LL now)
{
    if(mp[x][y]){
        flag[x][y]=now-mp[x][y];
        return;
    }
    mp[x][y]=now;
    d(x,y);
    dfs(x,y,now+1);
}
 
int main()
{
    LL T;
    scanf("%lld",&T);
    LL cas=0;
    while(T--){
        LL x,y,n;
        scanf("%lld %lld %lld",&x,&y,&n);
        while(n>1&&(x>30||y>30)){
            n--;
            d(x,y);
        }
        memset(mp,0,sizeof mp);
        dfs(x,y,0);
        while(n>1&&flag[x][y]==0){
            n--;
            d(x,y);
        }
        n=n%(flag[x][y]);
        if(!n) n=flag[x][y];
        while(n>1){
            n--;
            d(x,y);
        }
        printf("Case #%lld: %lld\n",++cas,x);
    }
 
 
    return 0;
}
 




Problem C. Sometimes Naive 


题意:

给你n个棒的长度,让你求出最多形成几个三角形

POINT:

用状压找出1的个数为3的倍数的答案。

然后dp更新就行了。


2.

最大团思路做,把3条边可以形成三角形的都找出来,作为一个点。

把点与点矛盾的连上一条边,这样问题就变成了求最大独立集。但是不是二分图。

所以取反图,求最大团。NP问题,随机算法跑,题目给你15秒。跑10000次稳过,其他看运气。


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define LL long long
const LL maxn =2048576;
LL dp[maxn];
LL a[22];
LL cnt;
LL three[maxn],cnt_three;
struct node
{
    LL ans;
    LL num;
    bool friend operator < (node a,node b){
        return a.num<b.num;
    }
}ans[maxn];
LL check(LL x)
{
    LL num[4];
    LL c=0;
    LL cn=0;
    while(x){
        c++;
        if(x&1){
            num[++cn]=a[c];
        }
        x>>=1;
    }
    if(num[1]+num[2]>num[3]&&num[3]+num[2]>num[1]&&num[1]+num[3]>num[2]){
        return 1;
    }
    return 0;
}
 
void f(LL x)
{
    LL b=x;
    LL num=0;
    while(x){
        if(x&1) num++;
        x>>=1;
    }
    if(num%3==0){
        ans[++cnt].ans=b;
        ans[cnt].num=num;
    }
    if(num==3){
        if(check(b)){
            three[++cnt_three]=b;
        }
    }
}
int main()
{
    LL T;
    scanf("%lld",&T);
    LL cas=0;
    while(T--){
        LL n;
        cnt_three=cnt=0;
        scanf("%lld",&n);
        memset(dp,0,sizeof dp);
        for(LL i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        for(LL i=0;i<(1<<n);i++){
            f(i);
        }
        dp[0]=1;
        sort(ans+1,ans+1+cnt);
        for(LL i=1;i<=cnt;i++){
            for(LL j=1;j<=cnt_three;j++){
                if(dp[ans[i].ans]==1&&(ans[i].ans&three[j])==0){
                    dp[ans[i].ans|three[j]]=1;
                }
            }
        }
        for(LL i=cnt;i>=1;i--){
            if(dp[ans[i].ans]){
                printf("Case #%lld: %lld\n",++cas,ans[i].num/3);
                break;
            }
        }
 
    }
 
    return 0;
}


2:


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <cstdlib>
#include <ctime>
using namespace std;
#define LL long long
const LL maxn = 2000+5;
LL a[22];
LL cnt;
LL check(LL x,LL y,LL z)
{
	if(a[x]+a[y]>a[z]&&a[x]+a[z]>a[y]&&a[y]+a[z]>a[x]){
		return (1<<x)|(1<<y)|(1<<z);
	}
	return -1;
}
LL dian[maxn];
LL mp[maxn][maxn];
LL b[maxn];
bool p[maxn];

void RANDOM()
{
	srand(time(NULL));//换成0不行
	for(LL i = 1;i <= cnt;i ++)
		swap(b[i],b[rand()%cnt+1]);
	return ;
}

LL JUDGE()
{
	for(LL i = 1;i <= cnt;i ++)
		p[i] = 0;
	LL ans = 0;
	for(LL i = 1;i <= cnt;i ++)
	{
		if(!p[i])
		{
			ans ++;
			for(LL j = i+1;j <= cnt;j ++)
			{
				if(!mp[b[i]][b[j]])
					p[j] = 1;
			}
		}
	}
	return ans;
}



int main()
{

//	srand(time(NULL));
//	cout<<rand();
	LL T,n;
	scanf("%lld",&T);
	LL cas=0;
	while(T--){
		cnt=0;
		scanf("%lld",&n);
		for(LL i=1;i<=n;i++){
			scanf("%lld",&a[i]);
		}
		for(LL i=1;i<=n;i++){
			for(LL j=i+1;j<=n;j++){
				for(LL k=j+1;k<=n;k++){
					LL now=check(i,j,k);
					if(now!=-1){
						dian[++cnt]=now;
					}
				}
			}
		}
		for(LL i=1;i<=cnt;i++){
			for(LL j=1;j<=cnt;j++){
				mp[i][j]=1;
				if(dian[i]&dian[j]){
					mp[i][j]=0;
				}
			}
		}
		for(LL i=1;i<=cnt;i++)
			b[i]=i;
		LL Max=0;
		for(LL i=1;i<=10000;i++){
			RANDOM();
			if(Max==n/3) break;
			Max=max(Max,JUDGE());
		}
		printf("Case #%lld: %lld\n",++cas,Max);
	}
	return 0;
}



Problem G: 最大公约数和最小公倍数问题


a*b=gcd*lcm.


个数就是1<<(lcm/gcd的【不同】质因数的个数的).


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
int num=0;
int flag[1000201];
 
void f(int x)
{
    for(int i=2;i<=x;i++){
        while(x%i==0){
            if(flag[i]==0){
                num++;
                flag[i]=1;
            }
            x=x/i;
        }
    }
    if(x!=1&&flag[x]==0)
        num++;
}
 
int main()
{
    int x,y;
    scanf("%d %d",&x,&y);
    if(x>y) swap(x, y);
    int now=y/x;
    if(now*x!=y){
        printf("0\n");
        return 0;
    }
    f(now);
    int ans = 1;
    for(int i=1;i<=num;i++){
        ans=ans*2;
    }
    cout<<ans<<endl;
    return 0;
}

总结:

被B题tle的头皮发麻,心态太脆弱了。

导致剩下3个小时处于神游状态!!

请给我反思一年!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值