记录49
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,water[110]={},t,min_=999,num=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>t;
for(int j=1;j<=m;j++){
if(min_>water[j]){
min_=water[j];
num=j;
//printf("最小情况:%d 编号:%d\n",min_,num);
}
}
water[num]+=t;
min_+=water[num];
}
sort(water+1,water+m+1);
cout<<water[m];
return 0;
}
题目传送门
https://www.luogu.com.cn/problem/P1190
突破点
每个龙头每秒钟的供水量相等,均为 1
👉时间跟接水量一样了
这些同学按接水顺序从 1 到 n 编号,i 号同学的接水量为 wi。接水开始时,1 到 m 号同学各占一个水龙头,并同时打开水龙头接水。当其中某名同学 j 完成其接水量要求 wj 后,下一名排队等候接水的同学 k 马上接替 j 同学的位置开始接水。
👉先接完水的先离开
按照上述接水规则,问所有同学都接完水需要多少秒。
👉最后一个接完水的时间
思路
- 输入要接水的量(即时间)
- 遍历最快完成的水龙头让同学过去排队
- 更新排队后水龙头的数据
代码简析
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,water[110]={},t,min_=999,num=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>t;
for(int j=1;j<=m;j++){
if(min_>water[j]){
min_=water[j];
num=j;
//printf("最小情况:%d 编号:%d\n",min_,num);
}
}
water[num]+=t;
min_+=water[num];
}
sort(water+1,water+m+1);
cout<<water[m];
return 0;
}
双重for循环就可以解决此题
外层for循环一个个接水的人,内层for循环找到最快结束的水龙头编号
if(min_>water[j]){}👉寻找最快结束的水龙头
min_=water[j];👉更新最快水龙头的时间值
num=j;👉记录下来最快编号
water[num]+=t;👉最快的水龙头排队
min_+=water[num];👉当前最快水龙头的时间更新
sort(water+1,water+m+1);👉水龙头结束时间由快到慢
cout<<water[m];👉最后一个结束的时间
补充
CSP-J 模拟类题目技巧完全汇总
一、什么是"模拟题"(CSP-J核心题型)
定义:严格按题目描述的规则、流程、步骤,一步步编码实现,不依赖复杂算法,考察细节处理和编码能力。
CSP-J中的占比:第1-2题80%是模拟,第3题50%是模拟。
二、高频模拟题型与识别特征
题型1:流程模拟(考频★★★★★)
特征:题目描述一个操作流程(如计算器、投票系统、排队) 关键词:"按照规则"、"依次处理"、"每一步"
例子:
2023 T1 小苹果:按规则分苹果
2022 T1 乘方:按步骤计算幂
题型2:字符串模拟(考频★★★★☆)
特征:按规则修改、匹配、构造字符串 关键词:"删除字符"、"替换"、"匹配模式"
例子:
密码生成器
字符串加密解密
题型3:日期/时间模拟(考频★★★☆☆)
特征:计算日期差、星期几、时间跨度 关键词:"第几天"、"经过多少天"、"星期"
题型4:游戏模拟(考频★★☆☆☆)
特征:模拟棋类游戏、走格子、胜负判定 关键词:"移动"、"轮到谁"、"获胜条件"
三、通用解题步骤(模板)
Step 1:读题画流程图(纸笔必备)
输入 → 初始化状态 → 循环处理 → 更新状态 → 输出结果 ↑_______________↓Step 2:定义状态变量
// 根据题目定义所有需要的状态 int day = 1; // 当前天数 int player = 0; // 当前玩家(0或1) string state = "init";// 当前状态 vector<int> queue; // 队列状态Step 3:主循环框架
while (!终止条件) { // 1. 读取当前操作/输入 cin >> op; // 2. 按规则处理 if (op == "A") { // 处理A规则 更新状态(); } else if (op == "B") { // 处理B规则 更新状态(); } // 3. 边界检查(越界、非法、结束) if (非法状态) break; // 4. 记录结果 ans.push_back(当前结果); }Step 4:输出结果
// 按题目要求格式输出 for (int x : ans) cout << x << endl;
四、核心技巧与防错指南
技巧1:下标从0还是从1?统一!
// ✅ 推荐:从1开始,避免负下标 int a[N]; for (int i = 1; i <= n; i++) cin >> a[i]; // ❌ 错误:混用0和1,导致计算错误 a[i-1] = a[i] + 1; // 容易越界技巧2:状态变量初始化
// 所有状态必须初始化,否则随机值 int step = 0; // 步数 bool gameOver = false; // 游戏结束标记 string curPlayer = "A"; // 当前玩家技巧3:字符串模拟用数组比string快
// 频繁修改字符时: char s[1005]; // ✅ 用char[],直接s[i]='x' // 比 string s; s[i]='x'; 更快技巧4:大数组用全局,模拟用局部
// 数据存储(全局,大) int a[1010][1010]; // 模拟状态(局部,小) int x = 0, y = 0; while (true) { ... }技巧5:调试技巧:中间输出法
// 在关键步骤输出状态,快速定位错误 if (debug) { cout << "Step=" << step << " Player=" << curPlayer << " Pos=" << x << "," << y << endl; }
五、常见陷阱与避坑指南
陷阱1:边界条件漏掉
错误:循环到
i < n,但题目可能有i <= n应对:读题时把所有≤、≥、<、>圈出来
陷阱2:状态更新顺序错误
// 错误示范:先更新位置,再检查是否越界 x += dx; // 可能越界 if (x > n) x = 1; // 补救,但逻辑混乱 // 正确示范:先检查,再更新 int nx = x + dx; if (nx > n) nx = 1; x = nx;陷阱3:字符串结束符'\0'
char s[1005]; cin >> s; int len = strlen(s); // ✅ 自动找到\0 s[len] = 'a'; // ❌ 可能越界! s[len+1] = '\0'; // ✅ 必须保证结尾有\0陷阱4:多组数据未清空状态
int T; cin >> T; while (T--) { // ❌ 错误:未清空上次状态 // vector<int> q; 应该在这里定义 // ✅ 正确:每组数据前清空 memset(vis, 0, sizeof(vis)); queue.clear(); }
六、高频模拟题模板代码
模板1:日期模拟(求星期几)
int days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; bool isLeap(int y) { return (y%4==0 && y%100!=0) || (y%400==0); } // 计算y-m-d是当年的第几天 int dayOfYear(int y, int m, int d) { int sum = d; for (int i = 1; i < m; i++) { sum += days[i]; if (i==2 && isLeap(y)) sum++; } return sum; } // 计算两个日期差多少天 int dateDiff(int y1, int m1, int d1, int y2, int m2, int d2) { // 从公元1年1月1日开始累加 // 或直接用循环模拟 }模板2:队列模拟(排队问题)
queue<int> q; // 排队队列 while (!gameOver) { int cur = q.front(); q.pop(); // 处理cur q.push(cur); // 下一轮继续 }模板3:投票模拟
int vote[N]; // 每个候选人票数 while (cin >> x) { if (x == -1) break; // 结束 vote[x]++; } // 找最大值 int winner = 0; for (int i = 1; i <= n; i++) if (vote[i] > vote[winner]) winner = i;
七、调试技巧(模拟题救命稻草)
打印每一轮状态:
for (int round = 1; round <= 100; round++) { // 处理逻辑 if (round <= 10) { // 只打印前10轮,避免输出太多 cout << "Round " << round << ": "; // 打印关键变量 } }
用assert断言:
#include <cassert> assert(x >= 1 && x <= n); // 若条件不满足,程序立即终止
对拍法:写暴力解法和你认为正确的解法,随机小数据对拍
八、CSP-J模拟题速查表
题目类型 关键状态 循环结构 复杂度 流程模拟 步骤计数器 while(有输入) O(n) 字符串模拟 当前位置指针 for(每个字符) O(len) 日期模拟 年月日变量 while(未到目标) O(天数) 游戏模拟 棋盘状态数组 while(!结束) O(步数)
九、一句话总结
CSP-J模拟题 = 读懂规则 + 定义状态变量 + while循环 + if分支,核心是细节不出错,边界要特判,状态要初始化。
908

被折叠的 条评论
为什么被折叠?



