洛谷 P1281 书的复制

题目背景

大多数人的错误原因:尽可能让前面的人少抄写,如果前几个人可以不写则不写,对应的人输出 0

不过,已经修改数据,保证每个人都有活可干。

题目描述

现在要把 m 本有顺序的书分给 k 个人复制(抄写),每一个人的抄写速度都一样,一本书不允许给两个(或以上)的人抄写,分给每一个人的书,必须是连续的,比如不能把第一、第三、第四本书给同一个人抄写。

现在请你设计一种方案,使得复制时间最短。复制时间为抄写页数最多的人用去的时间。

输入格式

第一行两个整数 m,k。

第二行 m 个整数,第 i 个整数表示第 i 本书的页数。

输出格式

共 k 行,每行两个整数,第 i 行表示第 i 个人抄写的书的起始编号和终止编号。 k 行的起始编号应该从小到大排列,如果有多解,则尽可能让前面的人少抄写。

输入输出样例

输入 

9 3
1 2 3 4 5 6 7 8 9

输出 

1 5
6 7
8 9

说明/提示

1≤k≤m≤500。

AC代码:

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

long long n, m, a[1010], x[1010], y[1010];			

bool oor(long long mid) {				
	long long cnt = 1, b = 0;
	for(int i=n;i>=1;i--) {	
		if(b + a[i] > mid){
			b = 0;
			cnt++;
		}	
		b += a[i];
	}
	return cnt <= m;
}

int find(long long left, long long right) {
	long long mid;
	while(left + 1 < right){
		mid = left + (right - left) / 2;
		if(oor(mid)) right = mid;
		else left = mid;
	} 
	return right;
}

int main() {
	long long left = 0, right = 0, b = 0, cnt = 1;
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		right += a[i];
		left = max(left, a[i]);
	}
	int finded = find(left, right);
	for(int i=1;i<=m;i++) {
		x[i] = 0;
		y[i] = 0;
	}
	y[1] = n;
	for(int i=n;i>=1;i--){
		if(b + a[i] > finded){
			b = 0;
			x[cnt] = i + 1;
			y[++cnt] = i;
		}
		b += a[i];
	}
	x[cnt] = 1;					
	for(int i=m;i>=1;i--) cout << x[i] << " " << y[i] << endl;
	return 0;
}
  • 测试点信息:

藏头诗 :

                                         《感恩有君》

                                                     [现代]-陨光-

                                            给君厚意心中存,

                                            个中情怀意韵深。

                                            关情幸得君相问,

                                            注眸难忘此般恩。

题目链接: 


    ### 关于 P1833 题目解析 P1833 是一道关于字符串处理的问题,具体来说是要求统计一段文字中不同单词的数量。为了高效解决这个问题,可以采用哈希表来记录各个单词出现的情况。 #### Python 实现方案 下面是一个基于Python实现的解决方案: ```python from collections import defaultdict def count_distinct_words(text): word_count = defaultdict(int) words = text.split() for word in words: cleaned_word = ''.join(filter(str.isalnum, word)).lower() # 清洗并转换成小写 if cleaned_word: word_count[cleaned_word] += 1 distinct_word_count = sum(1 for count in word_count.values() if count > 0) return distinct_word_count if __name__ == "__main__": input_text = input().strip() result = count_distinct_words(input_text) print(result) ``` 此程序首先读取输入的一段文本,接着通过`split()`函数分割这段文本成为单个词语列表;之后遍历这些词项,并利用正则表达式去除标点符号以及将其统一转为小写字母形式以便比较相同词汇的不同大小写的版本;最后统计去重后的唯一单词数量并输出结果[^1]。 #### C++ 实现方案 同样地,在C++中也可以采取类似的思路解决问题: ```cpp #include <iostream> #include <sstream> #include <map> #include <cctype> using namespace std; int main(){ string line; getline(cin,line); map<string,int> mp; stringstream ss(line); string s; while(ss >> s){ string temp = ""; for(auto ch : s){ if(isalpha(ch)){ temp+=tolower(ch); } } if(!temp.empty()){ ++mp[temp]; } } cout << mp.size()<< endl; } ``` 上述代码实现了同样的逻辑——接收一整行作为输入,使用stringstream按空格分隔单词,清理掉非字母字符并将它们全部变为小写后存入映射容器内计数,最终打印出独一无二的键值数目即为所求答案[^2]。
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值