# PBinfo #401 – Pachete_Multe – Rezolvare C++

Sursa: Codul lui Andrei
Limbaj: C++
Autor rezolvare: andrei

## Enunț

Cerinţa
Într-un depozit foarte mare există un raft cu n+1 spații de depozitare, numerotate de la 1 la n+1. Primele n spatii de depozitare sunt ocupate cu n pachete numerotate cu valori între 1 și n, iar spațiul de depozitare n+1 este gol.

Administratorul depozitului decide mutarea pachetelor, astfel încât pentru orice i, pachetul numerotat cu i să se afle în spațiul de depozitare i. Pentru aceasta se va folosi spațiul de depozitare suplimentar, n+1, singura manevră validă fiind mutarea unui pachet dintr-un spațiu de depozitare în altul, cu condiția ca acesta să fie gol.

Determinați o succesiune de manevre prin care fiecare pachet să fie în spațiul corect.

Date de intrare
Fişierul de intrare pachete_multe.in conţine pe prima linie numărul n, iar pe a doua linie n numere naturale separate prin spaţii. Al i-lea număr reprezintă numărul pachetului aflat în spațiul de depozitare i.

Date de ieşire
Fişierul de ieşire pachete_multe.out va conţine pe prima linie numărul M, reprezentând numărul de manevre efectuate. Pe fiecare dintre următoarele M linii se descrie o manevră, prin două numere i j, cu semnificația: se ia pachetul din spațiul i și se mută în spațiul j.

Restricţii şi precizări

1 ≤ n ≤ 100000 <— ATENȚIE AICI
pentru fiecare manevră i j efectuată, 1 ≤ i,j ≤ n+1, i ≠ j, iar spațiul j trebuie să fie gol
numărul de manevre realizate nu trebuie să fie minim

Exemplu:
pachete_multe.in

5
2 5 4 3 1 
pachete_multe.out

7
1 6
5 1
2 5
6 2
3 6
4 3
6 4
Explicație
Pachetele se vor muta în felul urmator.



2
5
4
3
1
_


_
5
4
3
1
2


1
5
4
3
_
2


1
_
4
3
5
2


1
2
4
3
5
_


1
2
_
3
5
4


1
2
3
_
5
4


1
2
3
4
5
_

## Cod sursă C++

```cpp
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cassert>
using namespace std;
#define NN 100005
ifstream fin("pachete_multe.in");
ofstream fout("pachete_multe.out");
int n, spatiu[NN], unde[NN], liber ,M;
struct manevra{
	int sursa,dest;
	manevra(){sursa = 0, dest = 0;}
	manevra(int i,int j){sursa = i, dest = j;}
	friend ostream& operator << (ostream &os, manevra x)
	{
		os << x.sursa << " " << x.dest;
		return os;
	}
};
manevra v[2*NN+10];
void muta(int i){
	v[++M] = manevra(i,liber);
	spatiu[liber] = spatiu[i];
	unde[spatiu[i]] = liber;
	spatiu[i] = 0;
	liber = i;
}
int main(){
	assert(fin >> n );
	for(int i=1 ; i<=n ; ++i)
		assert(fin >> spatiu[i]), unde[spatiu[i]] = i;
	liber = n+1;
	for(int i=1 ; i<=n ; ++i)
		if(spatiu[i]!=i)
		{
			//vad unde este pachetul i
			if(spatiu[i]!=0) //spatiul i este ocupat, il eliberez
				muta(i);
			muta(unde[i]);
		}
	fout << M << "\n";
	for(int i=1;i<=M;++i)
		fout << v[i] << "\n";
	return 0;
}
```

## Resurse

- [Pagina originală](https://codulluiandrei.ro/rezolvari/pbinfo/401)
- [Sursa C++](https://codulluiandrei.ro/rezolvari/pbinfo/401/cod.cpp)
- [Sursa pe GitHub](https://raw.githubusercontent.com/codulluiandrei/pbinfo/main/pbinfo-401/main.cpp)
- [Cursuri de informatică pentru BAC](https://codulluiandrei.ro/academia/info-curs/pachet-cpp/)
