Semaine3: plage de couverture - gourmande localement

couverture de l'intervalle C

Titre Description
droite numérique a n (1 <= n <= 25 000) un intervalle fermé [ai, bi], choisi pour couvrir une gamme aussi faible que segment spécifié [1, t] (1 < = t <= 1.000.000), ne peuvent pas -1 mots de sortie font.

Format d' entrée
des données d'entrée comprenant une pluralité d'ensembles, pour chaque ensemble de données: la
première ligne: n et t.
La deuxième ligne de la ligne n + 1: un intervalle de chaque ligne fermée.

Format de sortie
Pour chaque ensemble de données, le numéro de la section de sélection de sortie, les sorties impossibles -1.
Chaque sortie de données sur une ligne séparée.

échantillon

3 10
1 7
3 6
6 10

2

Avertissement doline
Ces sections couvrent le point entier, à savoir, (1,2) + (3,4) peut couvrir (1,4),
mais si (1,2) est (4,5), puis (2) pas couvrir 3.

Le temps peut être l' analogie apprécié:
par exemple comprend une première seconde [1,2) à gauche et à droite à des intervalles de temps ouvrir et fermer.
Deux secondes avant et un troisième et quatrième seconde peut couvrir l'ensemble des quatre premières secondes ~

En outre, la grande quantité de problème de données, ne pas utiliser iostream.

idées de résolution de problèmes
Cette question doline Cheetos, mais il y a une limite de temps (1000ms). Il a écrit plus de dix heures, environ 6 la version, une fois l'effondrement de la mentalité de vouloir abandonner. Aujourd'hui , les résultats ont ouvert une nouvelle Cpp, re-écrit à partir de zéro à nouveau après un résultat, il est métaphysique.
Je pense que maintenant il peut être ma dernière fois avec l'AC cin au lieu de scanf est sous ios :: sync_with_stdio (false) pour changer le résultat final. ( Est à blâmer pour le compilateur mal )
malheureux
ci - dessous WA après 12 AC code et l' analyse.

Voir cette question, nous avons pris la stratégie gourmande:
Pour chaque test, appuyer sur un petit au plus grand ordre, le point de départ de l'intervalle si plus de 1 s (s initial = 1), pas de solution, sinon, sélectionnez le point de départ des plus longs de l' intervalle . intervalle de sélection [ai, bi] doit être réglé sur le bi du point de départ, avant bi et partiellement coupé.

Tout d'abord, la quantité de données en vrac est très grand, donc si vous utilisez cin et Cout presque certainement expirer (qui ont prouvé hors de), donc ici que nous utilisons scanf ou ios :: cin sous sync_with_stdio (false).

Ensuite, nous utilisons un tableau de vecteur pour stocker la section d'entrée, le décrit ci-dessus genre.

Définition d' une len variable, valeur initiale 0.
Nous utilisons ensuite une boucle à boucle à travers toutes les sections du tableau, pour ces intervalles , nous avons:

  • La gamme actuelle de b i s inférieur au courant, puis choisissez c'est certainement une perte, abandonnée, continuer.
  • Un courant i est s + 1 intervalle inférieur ou égal (note), mise à jour len. len signifiant un moins pour tous les s + 1 intervalles, b est la distance de déplacement de la distance maximale, avide du noyau, à savoir, pour chaque couvercle, sont choisis pour couvrir une large gamme de cet intervalle possible, cette gamme peut être sélectionnée aussi peu que possible.
  • Un courant plus important que la section i s + 1, la sélection de cet intervalle sera vide, à savoir pas une couverture complète, contre le sens des problèmes, depuis été triés précédemment, il ne répond pas à toutes les sections suivantes, ainsi briser.

Après de la boucle, nous avons examiné la valeur de len. Si len est 0, décrit ci-dessus trois cas, l'absence du second. Si seulement le premier et le troisième cas, il sera vide, ensemble de données dont la description ne sont pas concluantes, nous avons -1 sortie, cet ensemble de traitement des données est terminée.

Après traitement, nous déplacer s courant au-dessus que le len b à la portée maximale. Puis le cycle recommence à partir d'une série d'opérations pour, jusqu'à ce que s == t;

Exemple de code

#include <iostream>
#include <algorithm>
#include <vector>
const int badans = -1;
using namespace std;

struct TC
{
	int a;
	int b;
};

vector<TC> arr;

bool cmp(const TC& m, const TC& n)
{
	return m.a < n.a;
}

int main()
{
	ios::sync_with_stdio(false);
	int n, s, t;
	while (cin >> n >> t)
	{
		arr.clear();
		s = 0;//因为下面代码中使用s+1来实现整点覆盖,由于s初始值应该是1,所以这里预设为0
		int ans = 0;
		bool isok = true;

		for (int i = 0; i < n; i++)
		{
			TC temTC;
			cin >> temTC.a >> temTC.b;
			arr.push_back(temTC);
		}

		sort(arr.begin(), arr.end(), cmp);

		//一个可选的剪枝
		//如果不用这个,那么nowpos的那个位置恒设为-1,即i=0
		int nowpos = -1;
		while (s < t)
		{
			int len = 0;
			int themaxone = 0;//记录使len最大的那个区间
			for (int i = nowpos + 1; i < arr.size(); i++)
			{
				if (arr[i].b <= s) continue;

				if (arr[i].a <= s + 1)//整点覆盖
				{
					int x = arr[i].b - s;
					if (x > len)
					{
						len = x;
						themaxone = i;
						nowpos = i;
					}
				}
				else break;
			}

			if (len == 0)//无解,直接输出-1并break出循环
			{
				cout << badans << endl;
				isok = false;
				break;
			}

			ans++;
			s = arr[themaxone].b;//刷新当前s
		}
		
		//如果不是通过break跳出循环的话说明是有解的
		if (isok) cout << ans << endl;
	}
	
	return 0;
}
Publié 21 articles originaux · a gagné les éloges 3 · Vues 417

Je suppose que tu aimes

Origine blog.csdn.net/qq_44506233/article/details/104702555
conseillé
Classement