列表

详情


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.

 
You don't need to find the quickest way, instead, output any of the solution. If there’s no solution or the minimum number of steps is more than 108, printing -1 is enough.

输入描述

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;
}

上一题