CodeCraft-21 and Codeforces Round #711 (Div. 2) A,B,C题题解

链接:https://codeforces.com/contest/1498/problem/A
A. GCD Sum
考虑到gcdSum 的分布比较密集,直接暴力即可

#include <iostream>
#include <vector>
#include <unordered_map> 
#include <cmath>
#include <map>
#include <cstring> 
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 1000010;
ll get(ll n)
{
    
    
	ll a = 0;
	while(n)
	{
    
    
		a+=n%10;
		n/=10;
	}
	return a;
}
ll gcd(ll a,ll b)
{
    
    
	return b==0?a:gcd(b,a%b);
}
int main()
{
    
    
	int t;cin>>t;
	ll n;
	while(t--)
	{
    
    
		scanf("%lld",&n);
		
		//cout<<"k="<<k<<endl;
		for(ll i=n;;i++)
		{
    
    
			ll k = get(i);
			if(gcd(i,k)>1)
			{
    
    
				printf("%lld\n",i);
				break;
			}
		}
	}
   	return 0;
}

B. Box Fitting
考虑贪心,对于每一个height,我们总是尽量的添加长的元素。 (首先考虑最长的,然后考虑第二长的,…)
例如
4 11
8 4 2 2
对于第一个height 我们考虑8,加入8 考虑第二大的4 但是无法加入,然后考虑第三大的2 可以加入,然后考虑第四大的2 无法加入。 第一个height加入的是8和2;
第二个height 加入的是4 2
用了2个height 于是输出2

实现方法1(优先队列): 优先队列中存储的是每个高度剩余的空间。

#include <iostream>
#include <vector>
#include <unordered_map> 
#include <cmath>
#include <map>
#include <cstring> 
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 100010;
int a[N];
int n,w;
void slove()
{
    
    
	scanf("%d%d",&n,&w);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	priority_queue<int> h;
	int ans = 1;
	sort(a+1,a+1+n);
	h.push(w-a[n]);
	for(int i=n-1;i>=1;i--)
	{
    
    
		int x = h.top();h.pop();
		if(a[i]<=x)
			h.push(x-a[i]);
		else
		{
    
    
			ans++;
			h.push(x);
			h.push(w-a[i]); 
		}
	}
	printf("%d\n",ans);
}
int main()
{
    
    
	int t;cin>>t;
	while(t--)
	{
    
    
		slove();
	}
	
   	return 0;
}

实现方法2(二进制枚举)
由题目知,每一个矩形的长度都是2^x,于是可以直接枚举。

#include <iostream>
#include <vector>
#include <unordered_map> 
#include <cmath>
#include <map>
#include <cstring> 
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 1000010;
int a[N];
int n,w;
void slove()
{
    
    
	scanf("%d%d",&n,&w);
	int x;
	memset(a,0,sizeof a);
	for(int i=1;i<=n;i++)
	{
    
    
		scanf("%d",&x);
		a[x]++;
	}
	int ans = 0;
	while(n)
	{
    
    
		int now = w;
		for(int i = 1<<19;i;i>>=1)
			while(now>=i&&a[i]) now-=i,a[i]--,n--;
		ans++;
	}
	printf("%d\n",ans);
}
int main()
{
    
    
	int t;cin>>t;
	while(t--)
	{
    
    
		slove();
	}
   	return 0;
}

C. Planar Reflections
dp。 定义f[i][j] 为即将撞i架飞机,decay age为j的粒子最终能产生几个粒子。
闫式dp分析法
在这里插入图片描述
于是f[i][j] = f[i-1][j]+f[n-i][j-1]
本菜鸡决定采用记忆化搜索

#include <iostream>
#include <vector>
#include <unordered_map> 
#include <cmath>
#include <map>
#include <cstring> 
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 1010,mod = 1e9+7;
int f[N][N];int n,k;
int dp(int i,int j)
{
    
    
	if(f[i][j]!=-1) return f[i][j];
	if(i==0||j==1) return f[i][j] = 1; 
	f[i][j] = (dp(i-1,j) + dp(n-i,j-1))%mod;
	return f[i][j];
}
int main()
{
    
    
	int t;cin>>t;
	while(t--)
	{
    
    
		cin>>n>>k;
		for(int i=0;i<=n;i++)
			for(int j=0;j<=k;j++)
				f[i][j] = -1;
		cout<<dp(n,k)<<"\n";
	}
   	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_50748356/article/details/115316574