Week 12

1.P1776 宝物筛选 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

解析:

        明显的背包DP,但本题数据较大,所以要进行优化。可以用二进制优化来处理。

多重背包的原理就是将一个物品不同个数当做新物品来处理,我们用二进制优化处理这一步。

        对于一个数,可以用不大于该数的2的n次幂加上余数组成。例如将19拆分成2,4,8,16,3,就可以用这五个数表示1~19的所有数。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int f[1000005];
int v[1000005],wi[1000005];
int cnt=1;
int main()
{
    int n,w;
    scanf("%d%d",&n,&w);
    for(int i=1;i<=n;++i)
    {
    	int a,b,m;
        scanf("%d%d%d",&a,&b,&m);
        //二进制优化代替原拆分
        for(int j=1;j<=m;j*=2) 
        {
            v[++cnt]=j*a,wi[cnt]=j*b;
            m-=j;
        }
        if(m) v[++cnt]=a*m,wi[cnt]=b*m;
    }
    
    for(int i=1;i<=cnt;++i)//多重背包 
    	for(int j=w;j>=wi[i];--j)
			f[j]=max(f[j],f[j-wi[i]]+v[i]);
    printf("%d\n",f[w]);
    return 0;
}

2.P1555 尴尬的数字 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

解析:

        考察进制转换。我们将给出的二进制数变一位在转化为三进制数,将次三进制数与给出的三进制数比较,如果只差一位,那么就是这个数。题目给出答案只有一个,那么不必再考虑其他问题。

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int a[50],b[50],c[50];
long long int mid;
int cnt1,cnt2;
void read1()
{
	char k;
	while((k=getchar())!='\n') a[++cnt1]=k-'0';
}
void read2()
{
	char k;
	while((k=getchar())!='\n') b[++cnt2]=k-'0';
	
}
void jin2()
{
	int tot=1;
	while(a[tot]==0) ++tot;
	int k=1;mid=0;
	for(int i=cnt1;i>=tot;--i)
	{
		mid+=a[i]*k;
		k*=2;
	}
}
void jin3(int n)
{
	int t=cnt2;
	while(n)
	{
		c[t--]=n%3;n/=3;
	}
}
int main()
{
	read1();read2();
	for(int i=1;i<=cnt1;++i)
	{
		if(a[i]==1)
		{
			a[i]=0;jin2();a[i]=1;
		}
		else if(a[i]==0)
		{
			a[i]=1;jin2();a[i]=0;
		}
		jin3(mid);
		int cnt=0;
		for(int i=1;i<=cnt2;++i)
		{
			if(b[i]!=c[i]) ++cnt;
			if(cnt>1) break;
		}
		if(cnt==1)
		{
			printf("%lld",mid);break;
		}
	}
	
	return 0;
}

3.P8845 [传智杯 #4 初赛] 小卡和质数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

解析:

        要想异或值为1,那必须满足二进制下只有末位不同,二进制下末位不同则必定一奇一偶。而质数中只有2这一个偶数,要想二进制下只有末位不同的质数只有3。所以两个质数异或为1只能一个2 ,一个3。

代码:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		if(a==1&&b==2||a==2&&b==1) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值