NC53273. 馕
描述
输入描述
从标准输入中读取数据。
第一行两个整数N,L。
接下来N行,每行L个整数,第i行第j个数为。
输出描述
输出数据到标准输出中。
如果无解,输出一行-1;
如果有解,首先输出N-1行,第i行两个整数,要求是一对满足的整数对。
接下来一行N个整数,第i个数表示。
你的输出需要满足:。。是一个1,...,N的排列。第i个人获得的总快乐度不小于。不必互质。可以证明,如果输入数据有解,那么一定存在一组满足上述条件的解。
示例1
输入:
2 5 2 7 1 8 2 3 1 4 1 5
输出:
14 5 2 1
说明:
在这组样例中,第一个人如果吃掉整个馕,会得到2+7+1+8+2=20的快乐度,第二个人如果吃掉整个馕,会获得3+1+4+1+5=14的快乐度。因此,如果第一个人获得不小于的快乐度,且第二个人获得不小于的快乐度,就是一组合法的解。示例2
输入:
7 1 1 2 3 4 5 6 7
输出:
1 7 2 7 3 7 4 7 5 7 6 7 3 1 4 2 7 6 5
说明:
在这组样例中,馕只有一种风味。只要把馕七等分,就是合法的方案,与无关。示例3
输入:
5 3 2 3 1 1 1 1 2 2 1 1 2 2 1 2 1
输出:
15 28 35 28 50 28 70 28 3 1 5 2 4
说明:
注意不必互质。C++14(g++5.4) 解法, 执行用时: 1607ms, 内存消耗: 64360K, 提交时间: 2020-04-19 14:49:08
#include <cstdio> #include <algorithm> #define ll long long using namespace std;const int Q=1<<11;struct dt{ll u,w;dt(){}dt(ll a,ll b){u=a,w=b;}void P(){printf("%lld %lld\n",u,w);}}s[Q][Q];bool operator<(dt a,dt b){return (long double)a.u*b.w<(long double)b.u*a.w;}ll f[Q];int b[Q],o[Q];int main(){int n,l;scanf("%d%d",&n,&l);for(int p=1;p<=n;p++){for(int i=1;i<=l;i++)scanf("%lld",&f[i]),f[i]+=f[i-1];for(int h=0,i=1;i<=n;i++){while(f[h+1]*n<f[l]*i)++h;ll p2=1LL*n*(f[h+1]-f[h]),p1=1LL*h*p2+f[l]*i-f[h]*n,g=__gcd(p1,p2);s[p][i]=dt(p1/g,p2/g);}}for(int i=1;i<=n;i++){int x=0;for(int j=1;j<=n;j++)if((!o[j])&&((!x)||s[j][i]<s[x][i]))x=j;o[x]=1;b[i]=x;}for(int i=1;i<n;i++)s[b[i]][i].P();for(int i=1;i<=n;i++)printf("%d ",b[i]);}