CSPOJ:1561: 【提高】买木头

样例输入 :
10 10000 8 20

样例输出:

201

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int l[10010],s[10010];
int n,m,suml=0,maxl=0;
bool check(int mid){
	int cnt=0;
	for(int i=1;i<=n;i++){
		cnt+=l[i]/mid*s[i];
	}
	return cnt>=m; 
} 
signed main(){
	cin>>n>>m>>l[1]>>s[1];
	for(int i=2;i<=n;i++){
		l[i]=((l[i-1]*37011+10193)%10000)+1;
		s[i]=((s[i-1]*73011+24793)%100)+1;
		suml+=l[i]*s[i];
		maxl=max(maxl,l[i]);	
	}
	if(suml<m){
		cout<<0;
		return 0;
	}
	int l=1,r=maxl,mid;
	while(l<r){
		mid=l+r+1>>1;
		if(check(mid)) l=mid;
		else           r=mid-1;
	}
	cout<<l;
    return 0;
}
┌───────────────┐
│   程序开始    │
└───────┬───────┘
        ▼
┌───────────────┐
│  声明全局变量  │
│ l[10010], s[10010] │
│ n, m, suml=0, maxl=0 │
└───────┬───────┘
        ▼
┌─────────────────────────────────┐
│         定义check函数           │
│  参数:mid(待检查的段长)      │
│  步骤1:初始化cnt=0             │
│  步骤2:循环i=1到n              │
│   ├─ 计算l[i]/mid * s[i]        │
│   └─ 累加至cnt                  │
│  步骤3:返回cnt >= m            │
└───────┬───────┘
        ▼
┌─────────────────────────────────┐
│         主函数main              │
│  步骤1:输入n, m, l[1], s[1]    │
│  步骤2:循环i=2到n              │
│   ├─ 生成l[i] = (l[i-1]*37011+10193)%10000 +1 │
│   ├─ 生成s[i] = (s[i-1]*73011+24793)%100 +1   │
│   ├─ suml += l[i] * s[i]        │
│   └─ maxl = max(maxl, l[i])     │
└───────┬───────┘
        ▼
┌─────────────────────────────────┐
│  判断suml < m?                 │
│  ├─ 是 → 输出0,程序结束        │
│  └─ 否 → 进入二分查找           │
└───────┬───────┘
        ▼
┌─────────────────────────────────┐
│       二分查找初始化            │
│  l=1, r=maxl, mid未定义         │
└───────┬───────┘
        ▼
┌─────────────────────────────────┐
│     循环:当l < r时             │
│  步骤1:mid = (l + r + 1) >> 1  │
│  步骤2:调用check(mid)?        │
│   ├─ 是 → l = mid               │
│   └─ 否 → r = mid - 1           │
└───────┬───────┘
        ▼
┌─────────────────────────────────┐
│       输出l(最大段长)         │
└───────┬───────┘
        ▼
┌───────────────┐
│   程序结束    │
└───────────────┘

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值