记录62
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,t;
bool f=0;
cin>>n;
for(int i=n;i>=0;i--){
cin>>t;
if(t==0) continue;
if(t>0&&f) cout<<'+';
if(abs(t)!=1||i==0) cout<<t;
if(t==-1&&i!=0) cout<<'-';
if(i>0) cout<<'x';
if(i>=2) cout<<'^'<<i;
if(t!=0&&!f) f=1;
}
return 0;
}
题目传送门
https://www.luogu.com.cn/problem/P1067
突破口
一元 n 次多项式可用如下的表达式表示:
f(x)=。。。其中,aixi 称为 i 次项,ai 称为 i 次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式
思路
模拟一个一元 n 次多项式,先搞定系数,再搞定x的次方
代码简析
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,t;
bool f=0;
cin>>n;
for(int i=n;i>=0;i--){
cin>>t;
if(t==0) continue;
if(t>0&&f) cout<<'+';
if(abs(t)!=1||i==0) cout<<t;
if(t==-1&&i!=0) cout<<'-';
if(i>0) cout<<'x';
if(i>=2) cout<<'^'<<i;
if(t!=0&&!f) f=1;
}
return 0;
}
int n(一元多项式的最高次数),t(输入的每个数字);
bool f=0; (对第一个数字特殊处理,如果是正数不用输出+号)
for(int i=n;i>=0;i--){} 👉 把每一个项按照次数递减顺序输出
if(t==0) continue; 👉 系数为0直接跳过这一项
if(t>0&&f) cout<<'+'; 👉 数字是整数,且是不是第一个数字,有+号
if(abs(t)!=1||i==0) cout<<t; 👉 系数不是1,或者是第最后一项,直接输出
注意:负数无论在第一项还是第n项,都需要带-符号
if(t==-1&&i!=0) cout<<'-'; 👉 系数为-1时,并且不是最后一项,系数1省略,只有-号
if(i>0) cout<<'x'; 👉 只要不是最后一项,都有x
if(i>=2) cout<<'^'<<i; 👉 除了最后两项项的x的次方要省略,其他的都要有次方
if(t!=0&&!f) f=1; 👉 保证第一项后的所有整数都带+号
补充
CSP-J字符串操作技巧完全汇总
一、输入输出处理(竞赛第一步)
1.1 不同读取方式
// 方式1:读取单词(遇空格/换行停止) string s; cin >> s; // 输入"hello world",s="hello" // 方式2:读取整行(含空格) string line; getline(cin, line); // 输入"hello world",line="hello world" // ⚠️ 注意:若前面用过cin,需先cin.ignore()清空缓冲区 // 方式3:读取到字符数组(C风格) char str[1005]; scanf("%s", str); // 读取单词 gets(str); // ⚠️ 危险!读取整行,易溢出,禁用 fgets(str, 1005, stdin); // 安全读取整行,但保留'\n'1.2 处理空格与换行
// 需求:读取含空格的字符串 // 错误:cin >> s会截断 // 正确: getline(cin, line); // 读取多个数字字符串 while (cin >> s) { // 自动忽略空格和换行 // 处理s }
二、基本遍历与修改(高频操作)
2.1 三种遍历方式
string s = "abcdef"; // 方式1:下标遍历(最通用) for (int i = 0; i < s.size(); i++) { s[i] = toupper(s[i]); // 转大写 } // 方式2:范围for(简洁) for (char &c : s) { // &引用可修改 if (c == 'a') c = 'b'; } // 方式3:迭代器(少用) for (auto it = s.begin(); it != s.end(); ++it) { *it = 'x'; }2.2 修改字符
// 单点修改 s[0] = 'A'; // O(1) // 尾部增删 s.push_back('x'); // 尾部加,O(1) s.pop_back(); // 尾部删,O(1) // 中间插入(性能差,避免) s.insert(3, "abc"); // O(n),慎用 // 删除区间 s.erase(3, 3); // 从位置3删3个字符,O(n),慎用竞赛铁律:中间插入/删除少用,用
push_back/pop_back+重构
三、查找与匹配(CSP-J核心)
3.1 子串查找
string s = "hello world hello"; size_t pos = s.find("world"); // 返回首次位置,找不到返回npos if (pos != string::npos) { // 找到 cout << pos; // 输出6 } // 查找所有出现 size_t start = 0; while ((pos = s.find("hello", start)) != string::npos) { cout << pos << " "; start = pos + 1; // 从下一个位置继续找 }3.2 字符查找
// 找字符首次出现 pos = s.find('o'); // O(n) // 反向查找 pos = s.rfind('o'); // 从后往前找陷阱:返回
size_t类型,不是int,比较时用string::npos(值为-1)
四、截取与拼接(高频)
4.1 截取子串
string s = "hello world"; string sub1 = s.substr(6, 5); // 从位置6截取5个字符,"world" string sub2 = s.substr(6); // 从位置6到末尾,"world" // 应用场景:分离路径 string path = "/home/user/file.txt"; size_t pos = path.rfind('/'); // 从后找'/' string dir = path.substr(0, pos); // "/home/user" string file = path.substr(pos + 1); // "file.txt"4.2 拼接字符串
// 方式1:+=(推荐) string s = "a"; s += "b"; // s="ab" s += 'c'; // s="abc" // 方式2:append() s.append("def"); // s="abcdef" // 方式3:+(创建临时对象,性能稍差) string s2 = s + "xyz"; // s不变,s2="abcxyz" // 方式4:stringstream(复杂拼接) ostringstream oss; oss << "ID:" << id << ", Score:" << score; string result = oss.str();竞赛铁律:**循环内用
+=,不要用+**(避免创建临时对象)
五、类型转换(竞赛必背)
** 5.1 数字 → 字符串 **
// 方式1:to_string()(C++11,推荐) int x = 123; string s = to_string(x); // "123" ll y = 1234567890123LL; string s2 = to_string(y); // "1234567890123" // 方式2:sprintf()(C风格) char buf[20]; sprintf(buf, "%d", x); string s = buf; // 方式3:stringstream(兼容C++98) ostringstream oss; oss << x; string s = oss.str();5.2 字符串 → 数字
// 方式1:stoi/stoll()(C++11,但Dev-C++可能不支持) string s = "123"; int x = stoi(s); // 转int ll y = stoll(s); // 转long long // 方式2:atoi/atoll()(C风格,需c_str()) int x = atoi(s.c_str()); // 转int ll y = atoll(s.c_str()); // 转long long // 方式3:stringstream(最安全) stringstream ss(s); int x; ss >> x; // 成功返回1,失败返回0 // 方式4:手动实现(竞赛推荐) int strToInt(string s) { int ans = 0, sign = 1, i = 0; if (s[0] == '-') { sign = -1; i = 1; } for (; i < (int)s.size(); i++) ans = ans * 10 + (s[i] - '0'); return ans * sign; }竞赛铁律:比赛中禁用
stoi(),用atoi()或手写,避免编译失败
六、高级技巧(CSP-J压轴题)
6.1 前缀/后缀处理
// 前缀和 ll pre[N]; for (int i = 0; i < n; i++) pre[i+1] = pre[i] + (s[i] - '0'); // 前缀哈希(滚动哈希) unsigned long long h = 0, base = 131; for (char c : s) { h = h * base + c; } // 前缀函数(KMP的next数组) int nxt[N]; for (int i = 1, j = 0; i < n; i++) { while (j > 0 && s[i] != s[j]) j = nxt[j-1]; if (s[i] == s[j]) j++; nxt[i] = j; }6.2 双指针技巧
// 场景:找最长无重复子串 int cnt[256] = {0}, left = 0, ans = 0; for (int right = 0; right < n; right++) { cnt[s[right]]++; while (cnt[s[right]] > 1) { // 重复移动左指针 cnt[s[left]]--; left++; } ans = max(ans, right - left + 1); }6.3 滑动窗口
// 场景:找包含所有模式串的最短子串 unordered_map<char, int> need, window; int left = 0, right = 0, valid = 0; while (right < n) { char c = s[right]; window[c]++; if (need[c] == window[c]) valid++; while (valid == need.size()) { // 找到窗口,更新答案 if (right - left + 1 < minLen) { minLen = right - left + 1; start = left; } char d = s[left]; if (need[d] == window[d]) valid--; window[d]--; left++; } right++; }6.4 字符串反转
// 方式1:reverse算法 reverse(s.begin(), s.end()); // O(n) // 方式2:手动交换 for (int i = 0, j = s.size() - 1; i < j; i++, j--) { swap(s[i], s[j]); }
七、性能优化(防TLE)
7.1 避免低效操作
// ❌ 极低效:循环内频繁字符串拼接 string ans; for (int i = 0; i < 1e6; i++) { ans += char('a' + i % 26); // O(n²),1e12次操作 } // ✅ 高效:预先reserve空间 ans.reserve(1e6); // 预先分配内存 for (int i = 0; i < 1e6; i++) { ans.push_back('a' + i % 26); // O(n) } // ✅ 更高效:用char[]再转string char buf[1000005]; int len = 0; for (int i = 0; i < 1e6; i++) { buf[len++] = 'a' + i % 26; } string ans(buf, len);7.2 减少字符串拷贝
// ❌ 低效:传值 void func(string s) { ... } // 拷贝一次 // ✅ 高效:传引用 void func(const string& s) { ... } // 零拷贝
八、竞赛实战模板(背下来)
模板1:处理多行字符串
int n; cin >> n; cin.ignore(); // 跳过换行 for (int i = 0; i < n; i++) { string line; getline(cin, line); // 处理line }模板2:字符串分割
vector<string> split(const string& s, char delim) { vector<string> res; stringstream ss(s); string item; while (getline(ss, item, delim)) { res.push_back(item); } return res; } // 使用:vector<string> parts = split("a,b,c", ',');模板3:快速字符计数
int cnt[256] = {0}; for (char c : s) cnt[c]++; // 找最多字符 char maxChar = 0; for (int i = 0; i < 256; i++) { if (cnt[i] > cnt[maxChar]) maxChar = i; }
九、一句话总结
CSP-J字符串=输入用cin+getline,遍历用范围for,查找用find(),转换用to_string()和手写stoll,高级用双指针+前缀和,中间插入删除要避免,比赛混用printf记得c_str()。
312

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



