Lien sujet: https://codeforces.com/contest/1472
A. Cartes pour amis
Sujet
Un morceau de papier mesure w en longueur et h en largeur. Si w ou h est un nombre pair, il peut être divisé en deux moitiés de papier. Répétez la même action pour les deux morceaux de papier et demandez si un morceau de le papier peut être divisé en pas moins de n
Idées
Décomposez w et h séparément et continuez à diviser par 2 jusqu'à ce qu'ils ne puissent pas être divisés, et divisez-les en parties t1 et t2, il y a donc des parties t1 * t2 au total.
Ici, vous pouvez diviser par la force, ou vous pouvez utiliser directement les opérations sur les bits, c'est-à-dire lowbit (prenez le nombre restant à partir de la position du dernier 1 dans le binaire).
Code AC
la violence
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
int t; cin >> t;
while(t --){
int w, h, n;
cin >> w >> h >> n;
int t1 = 1, t2 = 1;
while(w % 2 == 0) {
t1 *= 2;
w /= 2;
}
while(h % 2 == 0){
t2 *= 2;
h /= 2;
}
if(t1 * t2 >= n) puts("YES");
else puts("NO");
}
return 0;
}
lowbit
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x & (-x)
int main(){
int t; cin >> t;
while(t --){
int w, h, n;
cin >> w >> h >> n;
int t1 = lowbit(w), t2 = lowbit(h);
if(t1 * t2 >= n) puts("YES");
else puts("NO");
}
return 0;
}
B. Division équitable
Sujet
n morceaux de sucre, le poids est de 1 ou 2, demandez s'il peut être divisé en deux parties du même poids
Idées
Trouvez le nombre de 1, t1, le nombre de 2, t2 et le poids total s.
Si s est un nombre impair, cela ne fonctionnera certainement pas;
S'il est divisé en deux moitiés, le poids attribué à chaque personne est un nombre impair, mais il n'y a pas de bonbon avec un poids de 1, cela ne fonctionnera pas.
Code AC
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
int t; cin >> t;
while(t --){
int s = 0, n, t1 = 0, t2 = 0, x;
cin >> n;
while(n --){
cin >> x;
t1 += (x == 1);
t2 += (x == 2);
s += x;
}
if(s % 2){
puts("NO");
continue;
}
s /= 2;
if(s % 2 && !t1) puts("No");
else puts("YES");
}
return 0;
}
C. Sauts longs
Sujet
Les n nombres sont stockés dans le tableau a, à partir de la i-ème position, la position médiane tt est initialisée à i, puis la distance de a [tt] peut être sautée à chaque fois.
Si tt <= n, alors vous pouvez continuer à sauter, sinon le jeu se termine, tmp est la somme des poids du saut à mi-chemin, et demandez maintenant quelle est la valeur maximale de ce tmp.
Idées
Chaque position peut sauter tout le temps, sautant de n. Si vous traversez de gauche à droite, par exemple, si 1 peut sauter à 6 et 3 peut sauter à 6, alors 6 ici a sauté deux fois, beaucoup de répétitions Opération, mais on peut traverser de l'arrière vers l'avant, donc cela peut être équivalent à la mémorisation, un saut suffit.
Code AC
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
ll a[maxn], dp[maxn]; // dp[i]就是从i位置开始跳出n需要加的权值
int main(){
int t; cin >> t;
while(t --){
int n; scanf("%d",&n);
for(int i = 1; i <= n; i ++){
scanf("%lld", &a[i]);
}
for(int i = 1; i <= n; i ++) dp[i] = 0;
ll ans = 0;
for(int i = n; i >= 1; i --){
ll d = i + a[i];
dp[i] += a[i] + (d <= n ? dp[d] : 0);
ans = max(ans, dp[i]);
}
cout << ans << endl;
}
return 0;
}
D. Jeu pair-impair
Sujet
Deux personnes se relaient pour prendre n pierres jusqu'à ce qu'elles aient fini. Alice prend la première, Bob prend la deuxième.
Si le poids wi de la pierre prise par Alice est un nombre pair, alors son score sera ajouté wi, sinon il ne sera pas ajouté;
Si le poids wi de la pierre prise par Bob est impair, alors son score sera ajouté wi, sinon il ne sera pas ajouté.
Demandez qui gagne ou qui tire à la fin.
Idées
Si je veux choisir, je dois choisir le plus lourd à chaque fois. La meilleure façon d'ajouter des points. Si je ne peux pas ajouter de points, alors vous devez avoir ajouté des points. Non, je ne peux pas vous les ajouter, prenez-le .
Code AC
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
ll a[maxn];
int main(){
int t; cin >> t;
while(t --){
int n, x; cin >> n;
ll t1 = 0, t2 = 0;
for(int i = 1; i <= n; i ++) {
cin >> a[i];
}
sort(a + 1, a + n + 1, greater<int>()); //从大到小排序
for(int i = 1; i <= n; i ++){
if(i % 2 == 1 && a[i] % 2 == 0) t1 += a[i]; //Alice先手 偶数加分
if(i % 2 == 0 && a[i] % 2 == 1) t2 += a[i]; //Bob后手 奇数加分
}
if(t1 > t2) puts("Alice");
else if(t1 < t2) puts("Bob");
else puts("Tie");
}
return 0;
}
E. Placement correct
Sujet
N enfants s'alignent pour prendre des photos, et chaque enfant a les attributs de longueur et de largeur wi, hi. Si i doit être classé avant j, il doit satisfaire wi <wj && hi <hj ou wi <hj && hi <wj.
Maintenant, demandez pour chaque enfant i, affichez un indice (arbitraire) de l'enfant qui peut être disposé devant lui, s'il n'existe pas, sortie -1
Idées
Tout d'abord, s'il est stipulé que wi est la valeur la plus petite parmi (wi, hi) et que hi est la valeur la plus grande parmi (wi, hi), il suffit alors de voir si la condition wi <wj && hi <hj est satisfaite
Ensuite, vous pouvez trier d'abord par wi, puis par hi pour vous assurer que w à gauche est inférieur ou égal à w à droite;
L'idée des doubles pointeurs, i, j. i parcourt le tableau, j chasse, si a [j] .w <a [i] .w alors tmp met à jour la valeur minimale de a [j] .h, id est la position de la valeur minimale mise à jour, si tmp <a Dans le cas de [i] .h, alors l'enfant en position id peut se tenir devant l'enfant a [i] .id à ce moment.
Code AC
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x & (-x)
#define pp pair<int, int>
const int maxn = 2e5 + 10;
struct node{
int x, y, id;
bool operator < (const node &a) const{
if(x != a.x) return x < a.x;
return y < a.y;
}
}a[maxn];
int dp[maxn];
int main(){
int t, n;
cin >> t;
while(t --){
cin >> n;
for(int i = 1; i <= n; i ++){
cin >> a[i].x >> a[i].y;
if(a[i].x > a[i].y) swap(a[i].x, a[i].y);
a[i].id = i; dp[i] = -1;
}
sort(a + 1, a + n + 1);
int tmp = 0x3f3f3f3f, id = -1, j = 1;
for(int i = 1; i <= n; i ++){
while(j < i && a[j].x < a[i].x){
if(tmp > a[j].y){
tmp = a[j].y;
id = a[j].id;
} j ++;
}
if(tmp < a[i].y) dp[a[i].id] = id;
}
for(int i = 1; i <= n; i ++){
if(i > 1) cout << " ";
cout << dp[i];
}
cout << endl;
}
return 0;
}