Entraînement d'hiver 1.22

Entraînement d'hiver 1.22

A - Brainman

Contexte
Raymond Babbitt rend son frère Charlie fou. Récemment, Raymond a compté 246 cure-dents renversés sur le sol en un instant rien qu'en les regardant. Et il peut même compter les cartes de poker. Charlie adorerait aussi pouvoir faire des choses sympas comme ça. Il veut battre son frère dans une tâche similaire.

Problème
Voici ce à quoi pense Charlie. Imaginez que vous obtenez une séquence de N nombres. Le but est de déplacer les nombres de manière à ce qu'à la fin la séquence soit ordonnée. La seule opération autorisée est d'échanger deux nombres adjacents. Essayons un exemple:
Commencez par: 2 8 0 3
swap (2 8) 8 2 0 3
swap (2 0) 8 0 2 3
swap (2 3) 8 0 3 2
swap (8 0) 0 8 3 2
swap (8 3) 0 3 8 2
swap (8 2) 0 3 2 8
swap (3 2) 0 2 3 8
swap (3 8) 0 2 8 3
swap (8 3) 0 2 3 8
Donc la séquence (2 8 0 3) peut être trié avec neuf swaps de nombres adjacents. Cependant, il est même possible de le trier avec trois de ces swaps:
Commencez par: 2 8 0 3
swap (8 0) 2 0 8 3
swap (2 0) 0 2 8 3
swap (8 3) 0 2 3 8
La question est: quel est le nombre minimum de swaps de nombres adjacents pour trier une séquence donnée? Puisque Charlie n'a pas les capacités mentales de Raymond, il décide de tricher. C'est ici que vous entrez en jeu. Il vous demande d'écrire pour lui un programme informatique qui répond à la question. Soyez assuré qu'il paiera un très bon prix pour cela.

Contribution

La première ligne contient le nombre de scénarios.
Pour chaque scénario, on vous donne une ligne contenant d'abord la longueur N (1 <= N <= 1000) de la séquence, suivie des N éléments de la séquence (chaque élément est un entier compris entre [-1000000, 1000000]). Tous les nombres de cette ligne sont séparés par des blancs simples.

Production

Démarrez la sortie pour chaque scénario avec une ligne contenant «Scénario #i:», où i est le numéro du scénario commençant à 1. Ensuite, imprimez une seule ligne contenant le nombre minimal de swaps de nombres adjacents nécessaires pour trier les séquence. Terminez la sortie du scénario avec une ligne vide.

Exemple d'entrée

4
4 2 8 0 3
10 0 1 2 3 4 5 6 7 8 9
6 -42 23 6 28 -100 65537
5 0 0 0 0 0

Exemple de sortie

Scenario #1:
3

Scenario #2:
0

Scenario #3:
5

Scenario #4:
0

L'idée principale du sujet: pour trier la séquence donnée, quel est le nombre minimum d'échanges de nombres adjacents

Idée: L'échange d'éléments adjacents satisfait le tri par fusion. Pour un nombre de la séquence, le nombre de nombres qui sont plus grands à l'avant et inférieurs à ce qu'il est

Le logarithme inverse du nombre. Le logarithme inverse d'une séquence est la somme du logarithme inverse de tous les nombres de la séquence. Donc le sens de la question est de calculer le logarithme inverse d'une séquence

Le tri par fusion consiste à diviser la séquence a [ l , r ] en deux séquences a [ l , mid ] et a [ mid + 1, r ], à les fusionner et à les trier séparément, puis à fusionner et trier les deux séquences ordonnées. Dans le processus de fusion et de tri, soit l <= i <= mid , mid +1 <= j <= r , quand a [ i ] <= a [ j ], aucun logarithme inverse ne sera généré; et quand a [ i ]> a [ j ], alors dans la suite ordonnée a [ l , mid ], dansLes nombres après a [ i ] sont plus grands que a [ j ]. Mettez un [ j ] avant a [ i ], et le logarithme inverse doit ajouter mi-i +1

Le code principal:

void merge(int p,int m,int q){
	int i=p,j=m+1,k=i;
	while(i<=m&&j<=q){
		if(a[i]<=a[j])
		b[k++] = a[i++];
		else
		b[k++]=a[j++],ans+=m-i+1;
	}
	while(i<=m) b[k++] =a[i++];
	while(j<=q) b[k++] =a[j++];
	for(i = p;i<=q;++i)
	 a[i] = b[i];
}
void mergesort(int p,int q){
	if(p==q) return ;
	else{
		int m = (p+q)/2;
		mergesort(p,m);
		mergesort(m+1,q);
		merge(p,m,q); 
	}
} 

Code complet:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+6;
int a[N];
int b[N];
int ans = 0;
void merge(int p,int m,int q){
	int i=p,j=m+1,k=i;
	while(i<=m&&j<=q){
		if(a[i]<=a[j])
		b[k++] = a[i++];
		else
		b[k++]=a[j++],ans+=m-i+1;
	}
	while(i<=m) b[k++] =a[i++];
	while(j<=q) b[k++] =a[j++];
	for(i = p;i<=q;++i)
	 a[i] = b[i];
}
void mergesort(int p,int q){
	if(p==q) return ;
	else{
		int m = (p+q)/2;
		mergesort(p,m);
		mergesort(m+1,q);
		merge(p,m,q); 
	}
} 
int main(){
	int t,n;
	cin>>t;
	for(int i = 1; i<=t;++i){
		cin>>n;
		ans = 0;
		for(int j = 1;j<=n;++j)
		   cin>>a[j];
		mergesort(1,n);
		printf("Scenario #%d:\n",i);
		cout<<ans<<endl;
		cout<<endl; 
	}
	return 0;
}

B - Tri ultra-rapide

Dans ce problème, vous devez analyser un algorithme de tri particulier. L'algorithme traite une séquence de n entiers distincts en échangeant deux éléments de séquence adjacents jusqu'à ce que la séquence soit triée par ordre croissant. Pour la séquence d'entrée
9 1 0 5 4,
Ultra-QuickSort produit la sortie
0 1 4 5 9.
Votre tâche consiste à déterminer le nombre d'opérations d'échange dont Ultra-QuickSort a besoin pour trier une séquence d'entrée donnée.

Contribution

L'entrée contient plusieurs cas de test. Chaque scénario de test commence par une ligne contenant un seul entier n <500 000 - la longueur de la séquence d'entrée. Chacune des n lignes suivantes contient un seul entier 0 ≤ a [i] ≤ 999 999 999, le i-ème élément de séquence d'entrée. L'entrée se termine par une séquence de longueur n = 0. Cette séquence ne doit pas être traitée.

Production

Pour chaque séquence d'entrée, votre programme imprime une seule ligne contenant un nombre entier op, le nombre minimum d'opérations d'échange nécessaires pour trier la séquence d'entrée donnée.

Exemple d'entrée

5
9
1
0
5
4
3
1
2
3
0

Exemple de sortie

6
0

L'idée principale du sujet: étant donné n nombres entiers, triez de petit à grand, échangez deux nombres adjacents à échanger et trouvez le nombre minimum d'échanges

L'idée est la même que la première question, trouvez l'ordre inverse

Code complet:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 5e5+6;
int a[N];
int b[N];
long long ans;
void merge(int p,int m,int q){
	int i=p,j=m+1,k=i;
	while(i<=m&&j<=q){
		if(a[i]<=a[j])
		b[k++] = a[i++];
		else
		b[k++]=a[j++],ans+=m-i+1;
	}
	while(i<=m) b[k++] =a[i++];
	while(j<=q) b[k++] =a[j++];
	for(i = p;i<=q;++i)
	 a[i] = b[i];
}
void mergesort(int p,int q){
	if(p==q) return ;
	else{
		int m = (p+q)/2;
		mergesort(p,m);
		mergesort(m+1,q);
		merge(p,m,q); 
	}
}
int main(){
	int n;
	while(cin>>n&&n){
		ans = 0;
		for(int i = 1;i<=n;++i)
		    cin>>a[i];
		mergesort(1,n);
		cout<<ans<<endl;
	}
	
}

D - Fusion de mots

Dans des millions de journaux à travers les États-Unis, il existe un jeu de mots appelé Jumble. Le but de ce jeu est de résoudre une énigme, mais pour trouver les lettres qui apparaissent dans la réponse, il est nécessaire de déchiffrer quatre mots. Votre tâche est d'écrire un programme capable de déchiffrer les mots.

Contribution

L'entrée contient quatre parties: 1) un dictionnaire, qui comprend au moins un et au plus 100 mots, un par ligne; 2) une ligne contenant XXXXXX, qui signale la fin du dictionnaire; 3) un ou plusieurs «mots» brouillés que vous devez déchiffrer, chacun sur une ligne à part; et 4) une autre ligne contenant XXXXXX, qui signale la fin du fichier. Tous les mots, y compris les mots du dictionnaire et les mots brouillés, se composent uniquement de lettres minuscules anglaises et compteront au moins un et au plus six caractères. (Notez que la sentinelle XXXXXX contient des X majuscules.) Le dictionnaire n'est pas nécessairement trié, mais chaque mot du dictionnaire est unique.

Production

Pour chaque mot brouillé dans l'entrée, sortez une liste alphabétique de tous les mots du dictionnaire qui peuvent être formés en réorganisant les lettres dans le mot brouillé. Chaque mot de cette liste doit apparaître seul sur une ligne. Si la liste est vide (car aucun mot du dictionnaire ne peut être formé), affichez à la place la ligne «PAS UN MOT VALIDE». Dans les deux cas, affichez une ligne contenant six astérisques pour signaler la fin de la liste.

Exemple d'entrée

tarp
given
score
refund
only
trap
work
earn
course
pepper
part
XXXXXX
resco
nfudre
aptr
sett
oresuc
XXXXXX

Exemple de sortie

score
******
refund
******
part
tarp
trap
******
NOT A VALID WORD
******
course
******

L'idée principale du sujet: tout d'abord, donnez une série de chaînes, sous forme de dictionnaire, l'entrée rencontre ******, puis entrez une série de mots à trier et affichez les mots qui existent dans le dictionnaire pour chaque mot à trier., La disposition des mots peut être différente. Si vous ne connaissez pas un mot du dictionnaire, organisez-les dans l'ordre lexicographique. Si aucun mot correspondant n'est trouvé, affichez NOT A VALID WORD, et affiche un ensemble de mots correspondants ou NOT A pour chaque sortie. ****** après VALID WORD.

Idée: utilisez le dictionnaire de stockage de numéros de chaîne str [], s stocke les mots à trier et s1 est utilisé pour recevoir temporairement une chaîne de str;

Utilisez d'abord sort pour trier le dictionnaire, puis saisissez une chaîne à trier pour le trier. En même temps, s1 reçoit les mots du dictionnaire et les trie également, s1 == s, indiquant que le mot existe dans le dictionnaire

Code complet:

#include<iostream>
#include<algorithm>
#include<string> 
using namespace std;
const int N = 1e4+6;
string str[N],s,s1;
int cnt,flag;
int main(){
	while(cin>>str[cnt]&&str[cnt]!="XXXXXX"){
		cnt++;
	}
	sort(str,str+cnt);
	while(cin>>s&&s!="XXXXXX"){
		flag = 1;
		sort(s.begin(),s.end());
		for(int i = 0;i<cnt;++i){
			s1 = str[i];
			sort(s1.begin(),s1.end());
			if(s1==s){
				cout<<str[i]<<endl;
				flag = 0;
			}
		}
		if(flag) puts("NOT A VALID WORD");
		puts("******");
	}
	return 0;
}

Classement E

Bien qu'il existe aujourd'hui une liste de classement en temps réel pour le test informatique, le classement ci-dessus est uniquement basé sur le nombre de questions complétées, sans tenir compte de
la valeur de chaque question, il ne s'agit donc pas du classement final. Compte tenu de la ligne de score d'admission, veuillez rédiger un programme pour trouver les
candidats qui ont passé la ligne de score en dernier et imprimer leurs scores par ordre décroissant.

Contribution

L'entrée de test contient des informations pour plusieurs examens. La première ligne de chaque information de test donne le nombre de candidats N (0 <N
<1000), le nombre de questions de test M (0 <M <= 10) et la ligne de score (entier positif) G; la deuxième ligne donne la première question à Le score entier positif de la question M; les N lignes suivantes, chaque ligne donne
le numéro de billet d'admission d' un candidat (une chaîne de 20 au maximum), le nombre total m de questions que l'étudiant a résolues et le numéro de la question de la question m
(Le numéro de la question est de 1 à M).
Lorsque le nombre de candidats lus est de 0, la saisie est terminée et l'examen ne sera pas traité.

Production

Pour chaque test, indiquez d'abord le nombre n de candidats qui ne sont pas inférieurs à la ligne de score sur la première ligne, puis
indiquez le numéro du test et le score des candidats en ligne de haut en bas sur la ligne n, séparés par un espace. Si plusieurs candidats ont le même score, ils seront
affichés dans l'ordre croissant de leurs numéros d' examen .

Exemple d'entrée

4 5 25
10 10 12 13 15
CS004 3 5 1 3
CS003 5 2 4 1 3 5
CS002 2 1 2
CS001 3 2 3 5
1 2 40
10 30
CS001 1 2
2 3 20
10 10 10
CS000000000000000001 0
CS000000000000000002 2 1 2
0

Exemple de sortie

3
CS003 60
CS001 37
CS004 37
0
1
CS000000000000000002 20


        
  

L'idée principale: le score le plus élevé

Idée: utilisez une structure pour stocker le nombre et les scores des élèves, calculez le score total en fonction du nombre de questions résolues et du score de chaque question, et calculez le nombre de personnes qui franchissent la ligne et triez en fonction du score total

Code complet:

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int N = 1006;
struct data{
	string num;
	int score;
	bool operator <(data x)const{
	    return (score!=x.score)? score>x.score:num<x.num; 
	}
}s[N];
int cot;
int a[N];
int main(){
	int n,m,line;
	while(cin>>n&&n){
	   cin>>m>>line;
	   int sum,cnt;
	   cot = 0;
	   for(int i = 1;i<=m;++i)
	       cin>>a[i];
	    for(int i = 1;i<=n;++i){
	    	cin>>s[i].num>>cnt;
	    	sum = 0;
	    	for(int j = 1;j<=cnt;++j){
	    		int id;
	    		cin>>id;
	    		sum+=a[id];
			}
			s[i].score = sum;
			if(sum>=line) cot++;
		}
		cout<<cot<<endl;
		sort(s+1,s+1+n);
		for(int i = 1;i<=cot;++i){
			cout<<s[i].num<<" "<<s[i].score<<endl;
		}
	}

	return 0;
} 

F - Heure des élections

Les vaches ont leur première élection après avoir renversé le fermier tyrannique John, et Bessie est l'une des N vaches (1 ≤ N ≤ 50 000) à la présidence. Cependant, avant que l'élection ne se produise, Bessie veut déterminer qui a les meilleures chances de gagner.

L'élection se déroule en deux tours. Au premier tour, les vaches K (1 ≤ KN ) avec le plus de voix passent au second tour. Au second tour, la vache avec le plus de voix devient présidente.

Étant donné que la vache i s'attend à obtenir des votes Ai (1 ≤ Ai ≤ 1.000.000.000) au premier tour et des votes Bi (1 ≤ Bi ≤ 1.000.000.000) au second tour (si elle réussit), déterminez quelle vache devrait gagner l'élection. Heureusement pour vous, aucun décompte des voix n'apparaît deux fois dans la liste Ai ; de même, aucun décompte des voix n'apparaît deux fois dans la liste Bi .

Contribution

* Ligne 1: Deux entiers séparés par des espaces: N et K
* Lignes 2… N +1: La ligne i + 1 contient deux entiers séparés par des espaces: Ai et Bi

Production

* Ligne 1: L'index de la vache qui devrait remporter l'élection.

Exemple d'entrée

5 3
3 10
9 2
5 6
8 4
6 5

Exemple de sortie

5

L'idée principale: les vaches se présentent à la présidence. Il y a deux tours de scrutin. Les k premières vaches du premier tour de scrutin peuvent voter au second tour, et finalement indiquer le numéro de la vache la plus susceptible de réussir. l'élection (le plus de votes)

Idée: La structure stocke les votes et les nombres de chaque vache en deux tours. Le premier tour est trié par le nombre de votes obtenus au tour a par ordre décroissant, et le second tour est trié par le nombre de voix obtenues par les k vaches avant le premier tour, et enfin le numéro de la vache est sorti.

Code complet:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 5e4+6;
struct data{
	ll a,b;
	int id;
}d[N];
int n,k;
bool cmpa(data p,data q){
	return p.a>q.a;
}
bool cmpb(data p,data q){
	return p.b>q.b;
}
int main(){
	cin>>n>>k;
	for(int i = 1;i<=n;++i){
		cin>>d[i].a>>d[i].b;
		d[i].id = i;
	}
	sort(d+1,d+n+1,cmpa);
	sort(d+1,d+k+1,cmpb);
	printf("%d\n",d[1].id);
	return 0;
}

G - Hôtel de vacances

M. et Mme Smith vont au bord de la mer pour leurs vacances. Avant de commencer, ils doivent choisir un hôtel. Ils ont obtenu une liste d'hôtels sur Internet et souhaitent choisir des hôtels candidats bon marché et proches du bord de mer. Un candidat hôtel M répond à deux exigences:

  1. Tout hôtel plus proche du bord de mer que M coûtera plus cher que M.
  2. Tout hôtel moins cher que M sera plus éloigné du bord de mer que M.

Contribution

Il existe plusieurs cas de test. La première ligne de chaque cas de test est un entier N (1 <= N <= 10000), qui est le nombre d'hôtels. Chacune des N lignes suivantes décrit un hôtel, contenant deux entiers D et C (1 <= D, C <= 10000). D signifie la distance entre l'hôtel et le bord de mer, et C signifie le coût du séjour à l'hôtel. Vous pouvez supposer qu'il n'y a pas deux hôtels avec les mêmes D et C. Un cas de test avec N = 0 termine l'entrée et ne doit pas être traité.

Production

Pour chaque cas de test, vous devez afficher une ligne contenant un entier, qui est le numéro de tous les hôtels candidats.

Exemple d'entrée

5
300 100
100 300
400 200
200 400
100 500
0

Exemple de sortie

2

Idée principale:

Les Smith vont à la plage pour des vacances et avant de partir, ils doivent choisir un hôtel. Ils ont obtenu une liste d'hôtels sur Internet, à partir de laquelle ils voulaient choisir des hôtels bon marché proches de la plage. Le Candidat Hotel M doit répondre à deux exigences:

• 1. Les hôtels plus proches de la plage que M sont plus chers que M.

• 2. que M hôtels bon marché loin de la plage que M loin.

Indiquez le nombre d'hôtels candidats pouvant remplir les conditions

Idée: La structure stocke la distance et le prix de chaque hôtel. Il existe deux méthodes de tri. 1. Trier par prix comme premier mot-clé, puis trouver l'hôtel le plus proche, 2. Trier par distance comme premier mot-clé, trouver le prix le moins cher

Code complet:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+6;
struct data{
	int dis,cs;
	bool operator<(data x){
		return cs==x.cs? dis<x.dis:cs<x.cs;
	}
}d[N];
int n;
int main(){
	while(cin>>n&&n){
		int ans = 0;
		for(int i = 1; i<=n;++i){
			cin>>d[i].dis>>d[i].cs;
		}
		sort(d+1,d+n+1);
		int minx = 99999999;
		for(int i = 1;i<=n;++i){
			if(d[i].dis<minx){
				minx = d[i].dis;
				ans++;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

La structure stocke la distance et le prix de chaque hôtel. Il existe deux méthodes de tri, 1. Trier par prix comme première clé, puis trouver l'hôtel le plus proche, 2. Trier par distance comme première clé, trouver le prix le moins cher

Code complet:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+6;
struct data{
	int dis,cs;
	bool operator<(data x){
		return cs==x.cs? dis<x.dis:cs<x.cs;
	}
}d[N];
int n;
int main(){
	while(cin>>n&&n){
		int ans = 0;
		for(int i = 1; i<=n;++i){
			cin>>d[i].dis>>d[i].cs;
		}
		sort(d+1,d+n+1);
		int minx = 99999999;
		for(int i = 1;i<=n;++i){
			if(d[i].dis<minx){
				minx = d[i].dis;
				ans++;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_45719435/article/details/112991584
conseillé
Classement