Enlace: https://codeforces.com/contest/1498/problem/A
A. GCD Sum
Teniendo en cuenta la densa distribución de gcdSum, la violencia directa es suficiente
#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
considera codicia Para cada altura, siempre tratamos de agregar elementos lo más largos posible. (Primero considere el más largo, luego considere el segundo más largo, ...)
Por ejemplo,
4 11
8 4 2 2
Para la primera altura, consideramos 8, y sumamos 8 para considerar el segundo 4 más grande pero no se puede unir, y luego consideramos el tercer 2 más grande puede unirse, y luego considere que el cuarto 2 más grande no puede unirse. La primera altura es 8 y 2; la
segunda altura es 4, 2
usa 2 alturas, por lo que la salida es 2.
Método de implementación 1 (cola de prioridad): La cola de prioridad almacena el espacio restante de cada altura.
#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;
}
El método de implementación 2 (enumeración binaria)
se conoce por el título, la longitud de cada rectángulo es 2 ^ x, por lo que se puede enumerar directamente.
#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. Reflexiones
planas dp. Defina f [i] [j] como si estuviera a punto de chocar contra un plano i, y una partícula con una edad de desintegración de j puede eventualmente producir varias partículas.
Método de análisis de dp de Yan,
por lo que f [i] [j] = f [i-1] [j] + f [ni] [j-1]
Ben Caiji decidió utilizar la búsqueda de memoria
#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;
}