P14342 [JOISC 2019] 馕 / Naan 题解
题目链接:P14342 [JOISC 2019] 馕 / Naan
非常水的题,可能不到蓝
有一个直接的贪心,每次取最最短的,但是显然是错的。考虑题目并没有要求让我们剩下的最小,我们可以求出每个人吃达到 $ \frac{1}{n}, \frac{2}{n}, \cdots , \frac{n-1}{n} $ 的位置,然后第 $ i $ 段的人取所有可以取的 $ \frac{i}{n} $ 最小值,显然其他人均大于等于他,所以下一个取哪个位置都是可以的。
本题难点在代码实现
代码:
#include<bits/stdc++.h>
#define time(null) chrono::steady_clock::now().time_since_epoch().count()
#define int long long
#define uint unsigned long long
#define debug() cout<<"come here\n"
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define pb push_back
#define Code return
#define by 0
#define MCYYDS ;
using namespace std;
int qpow(int a,int b,int p=INF){int ret=1;while(b){if(b&1)ret=(ret*a)%p;a=(a*a)%p;b>>=1;}return ret;}
inline int read(){int ret=0,f=1;char ch=getchar();while(ch<'0'||ch>'9')f=(ch=='-'?-1:f),ch=getchar();while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();return ret*f;}
inline void write(int x){if(x<0){putchar('-');write(-x);return ;}if(x>9)write(x/10);putchar((char)(x%10+48));}
inline void writech(int x,char ch){write(x);putchar(ch);}
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
int n=read(),m=read();
vector<vector<int> > a(n+1,vector<int>(m+1,0)),b(n+1,vector<int>(n+1,0)),c(n+1,vector<int>(n+1,0));
for(int i=1;i<=n;i++)
{
int sum=0;
for(int j=1;j<=m;j++)
{
a[i][j]=read();
sum+=a[i][j];
}
int now=0,pos=1;
for(int j=1;j<=n;j++)
{
while((now+a[i][pos])*n<sum*j)
{
now+=a[i][pos];
pos++;
}
b[i][j]=sum*j-now*n+(pos-1)*n*a[i][pos];
c[i][j]=n*a[i][pos];
}
}
vector<int> ans(n+1,0),vis(n+1,0);
for(int i=1;i<=n;i++)
{
int mn1=INF,mn2=INF,id=0;
for(int j=1;j<=n;j++)
{
if(vis[j])continue;
if(id==0||(__int128)b[j][i]*mn2<(__int128)mn1*c[j][i])
{
id=j;
mn1=b[j][i];
mn2=c[j][i];
}
}
ans[i]=id;
vis[id]=1;
if(i!=n)
{
writech(mn1,' ');
writech(mn2,'\n');
}
}
for(int i=1;i<=n;i++)
{
writech(ans[i],' ');
}
Code by MCYYDS
}

浙公网安备 33010602011771号