P5051の题解

题目传送门

Description

把 m 个人放在 n 个队伍里,规则如下:

  • 每次往一个队伍中放入 k 个人。

  • 顺序为: 1 t h − > 2 t h − > … … − > n t h − > … … − > 1 t h − > … … 1^{th}->2^{th}->……->n^{th}->……->1^{th}->…… 1th>2th>>nth>>1th> 并以此类推,直到剩下的人数小于 k 。

  • 当剩下的人数小于 k 时,将此时剩下的所有人放入当前队伍中。

输入一行三个数,分别是队伍数 n ,放入人数 k ,总人数 m 。

输出一行 n 个数,分别是这 1 到 n 个队伍中的人数。

思路

纯模拟!

  1. 当 m>=k 时,开始或继续模拟。

  2. 正方向:填充并更新 m 。

  3. 反方向(从 n-1 到 2 ):填充并更新 m 。

  4. 回到第一步

Answer:

AC Record

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn=2e5+10; //数据范围200,000 
const int inf=1e9+7;
int n,m,k;
int cow[maxn];

//---------------------------快读 

inline int read() {
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
	return s*w;
}

//---------------------------- 

inline void go() { //正方向入队伍 
	if(m==0) return;
	for(int i=1; i<=n; ++i) {
		if(m<k) { //人不够,剩下的全放 
			cow[i]+=m;
			m=0;
		} else {
			cow[i]+=k;
			m-=k;
		}
	}
}

inline void back() { //反方向入队伍
	if(m==0) return;
	for(int i=n-1; i>1; --i) { //i是从 n 到 2 的 
		if(m<k) { //人不够,剩下的全放
			cow[i]+=m;
			m=0;
		} else { 
			cow[i]+=k;
			m-=k;
		}
	}
}

inline void work() {
	while(m>=k) { //可以继续放 
		go(); // 正方向 
		back(); // 反方向 
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	n=read();
	k=read();
	m=read();
	memset(cow,0,sizeof cow); //初始化,可有可无 
	work();
	for(int i=1; i<=n; ++i) cout<<cow[i]<<' '; //输出 
	return 0;
} //记得开 O2 

温馨提醒(如果你看到了这里):由于本题是纯模拟题,所以时间复杂度大概为 O ( n m k ) O(\frac{nm}{k}) O(knm) ,所以记得吸氧哟,不然会 tle 三个点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值