NC15734. Trees Transplanting
描述
It’s universally acknowledged that there’re innumerable trees in the campus of HUST.
You’ve found N forests under the management of a strange-tempered ranger. He told you that the i-th forest consisted of ai trees, and you can transplant these trees between any two forests i and j in such a strange rule: if and only if ai<=aj, then you could transplant ai trees from the forest j to the forest i. Now you want to know if you could make it that only two forests remain non-empty at last after some operations.
输入描述
The first line contains a integer N, the number of forests.The next line are N integers following, indicating the initial number of trees in each forest, a1, a2, a3, ... ,an,.
输出描述
In the first line you output an integer K, the number of steps in your solution.Then K lines follow, in each line are two integers i and j, indicating a movement from the forest i to the forest j.
示例1
输入:
4 1 2 1 4
输出:
2 3 1 2 1
C++14(g++5.4) 解法, 执行用时: 63ms, 内存消耗: 3672K, 提交时间: 2019-07-23 22:37:16
#include <iostream> #include <vector> #include <utility> #include <algorithm> int main() { int n, a; std::cin >> n; std::vector<std::pair<int, int>> trees; for (int i = 1; i <= n; i++) { std::cin >> a; trees.emplace_back(a, i); } std::vector<std::pair<int, int>> ops; for (auto it = trees.begin(); it + 2 < trees.end(); it++) { std::sort(it, it + 3); int t = it[1].first / it[0].first; for (int i = 1; i <= t; i <<= 1) { if (i & t) { it[1].first -= it[0].first; it[0].first <<= 1; ops.emplace_back(it[1].second, it[0].second); } else { it[2].first -= it[0].first; it[0].first <<= 1; ops.emplace_back(it[2].second, it[0].second); } } std::swap(it[0], it[1]); if (it[0].first) { it--; } } std::cout << ops.size() << '\n'; for (auto &op: ops) { std::cout << op.first << ' ' << op.second << '\n'; } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 57ms, 内存消耗: 3560K, 提交时间: 2020-03-24 23:01:59
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int maxn=1e3+10; const int maxv=1e6+10; struct data { int v,p; }z[maxn]; int n,tmp,tot; int ansi[maxv],ansj[maxv]; void pushans(int i,int j) { tot++; ansi[tot]=i; ansj[tot]=j; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&z[i].v),z[i].p=i; for(int i=1;i<=n/2;i++) swap(z[i],z[i+n/2]); for(int i=1;i<=n-2;i+=(bool(!z[i].v))) { if(z[i].v>z[i+1].v) swap(z[i],z[i+1]); if(z[i+1].v>z[i+2].v) swap(z[i+1],z[i+2]); if(z[i].v>z[i+1].v) swap(z[i],z[i+1]); tmp=z[i+1].v/z[i].v; for(int j=1;j<=tmp;j<<=1) if((j&tmp)!=0) z[i+1].v-=z[i].v,z[i].v<<=1,pushans(z[i+1].p,z[i].p); else z[i+2].v-=z[i].v,z[i].v<<=1,pushans(z[i+2].p,z[i].p); swap(z[i],z[i+1]); } printf("%d\n",tot); for(int i=1;i<=tot;i++) printf("%d %d\n",ansi[i],ansj[i]); return 0; }