CodeCraft-21およびCodeforcesRound#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.ボックスフィッティング
は貪欲を考慮します。高さごとに、常に可能な限り長い要素を追加しようとします。(最初に最も長いものを検討し、次に2番目に長いものを検討します...)
たとえば、
4 11
8 4 2 2
最初の高さについては8を検討し、8を加算して2番目に大きい4を検討しますが、結合できません。 3番目に大きい2は参加でき、4番目に大きい2は参加できないと見なします。最初の高さは8と2、2
番目の高さは
4、2は2つの高さを使用するため、出力は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.平面反射
dp。f [i] [j]をi平面にぶつかろうとしていると定義すると、崩壊年齢がjの粒子は、最終的にいくつかの粒子を生成する可能性があります。
Yanのdp分析方法である
ここに画像の説明を挿入
ため、f [i] [j] = f [i-1] [j] + f [ni] [j-1]
BenCaijiはメモリ検索を使用することにしました。

#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