1003 我要通过
通过观察不难发现在一个规律:P之前A的个数*P和T之间A的个数等于T之后A的个数答案才正确
总结一下如何才能答案正确?
1.必须只能有P,A,T这三种字符
2.P和T之间必须要有A
3.P之前A的个数*P和T之间A的个数等于T之后A的个数
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n; cin >> n;
while(n--){
map<char,int> mp;
string s; cin >> s;
int len = s.size();
bool flag = true;
int ppos = 0,tpos = 0,cntbefore = 0,cntafter = 0,cnt = 0;
for(int i = 0; i < len; i++){
if((s[i] >= 'B' && s[i] < 'P')||(s[i]> 'P' &&s[i] < 'T') || (s[i] > 'T')){
flag = false;
}
if(s[i] == 'P') ppos = i;
if(s[i] == 'T') tpos = i;
mp[s[i]]++;
if(mp['P'] == 0 && s[i] == 'A') cntbefore++;
if(mp['P'] == 1 && s[i] == 'A' && mp['T'] == 1) cntafter++;
if(mp['P'] == 1 && mp['T'] == 0 && s[i] == 'A') cnt ++;
}
if(mp['P'] != 1 || mp['T'] != 1 || tpos - ppos <= 1) flag = false;
if(flag && cnt * cntbefore != cntafter) flag = false;
cout << (flag ? "YES\n" : "NO\n");
}
return 0;
}
1005 继续(3n+1)猜想
这个地方我误解了题目,我以为只需要把k这个数转化为1的过程中的数 记录下来即可确定关键数字。没有想到是要把k个数字每个数字都转化为1过程中的数做记录
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int k;
cin >> k;
vector<int> nums(k);
map<int, int> mp;
// 读取所有的数字
for (int i = 0; i < k; ++i) {
cin >> nums[i];
}
// 生成所有数字的卡拉兹序列,并标记被覆盖的数字
for (int i = 0; i < k; ++i) {
int x = nums[i];
while (x != 1) {
if (x % 2 == 1) x = 3 * x + 1;
x /= 2;
mp[x] = 1; // 标记为已覆盖
}
}
// 筛选出关键数字
vector<int> res;
for (int i = 0; i < k; ++i) {
if (mp.find(nums[i]) == mp.end()) {
res.push_back(nums[i]);
}
}
// 按从大到小的顺序排序并输出
sort(res.begin(), res.end(), greater<int>());
for (int i = 0; i < res.size(); ++i) {
cout << res[i];
if (i + 1 != res.size()) cout << " ";
}
return 0;
}
1006 换个格式输出整数
这个地方把整数先转化为字符串类型,这样本来整数获取每个位的数字是倒过来的,转化为字符串后,就可以正着处理。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
string s;
string str_n = to_string(n); // 将 n 转换为字符串
int len = str_n.length();
for(int i = 0; i < len; i++) {
int digit = str_n[i] - '0'; // 提取当前位的数字
if (i == len - 3) {
for (int j = 0; j < digit; j++) {
s += 'B';
}
} else if (i == len - 2) { // 处理十位数
for (int j = 0; j < digit; j++) {
s += 'S';
}
} else { // 处理个位数
for (int j = 1; j <= digit; j++) {
s += ('0' + j);
}
}
}
cout << s << endl;
return 0;
}
1007 素数对猜想
这里要注意prime[i+1] < n
运用埃氏筛选法获取质数表 -> 循环统计d == 2的对数
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5+10;
int prime[N],cnt;
bool st[N];
void get_prime(){
for(int i = 2; i <= N; i++){
if(!st[i]){
prime[cnt++] = i;
for(int j = i + i; j <= N; j+= i){
st[j] = true;
}
}
}
}
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n; cin >> n;
get_prime();
int ans = 0;
for(int i = 1; prime[i + 1] <= n; i++){
int d = prime[i+1] - prime[i];
//cout << prime[i+1] << " " <<prime[i] <<'\n';
if(d == 2) ans++;
}
cout << ans <<'\n';
return 0;
}
1008 数组元素循环右移问题
#include <bits/stdc++.h>
using namespace std;
const int N = 220;
int a[N],b[N];
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n,m; cin >> n >> m;
for(int i = 0; i < n; i++) cin >> a[i];
for(int i = 0; i < n; i++){
// cout<<(i+m)%n<<" ";
b[(i + m) % n] = a[i];
}
for(int i = 0; i < n; i++){
cout << b[i];
if(i != n - 1) cout << " ";
}
return 0;
}
1009 说反话
记得每次都需要把tmp清空
基本思路:根据空格来分割字符串,储存到vector中,然后再利用reverse函数来翻转输出
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
string s;
getline(cin,s);
vector<string> ans;
string tmp = "";
for(int i = 0; i < s.size(); i++){
if(s[i] != ' ' && s[i] != '\n') {
tmp += s[i];
} else {
if(!tmp.empty()) {
ans.push_back(tmp);
tmp.clear(); // 清空 tmp 以准备下一个单词
}
}
}
if(!tmp.empty()) {
ans.push_back(tmp); // 将最后一个单词加入 ans
}
reverse(ans.begin(),ans.end());
for(int i = 0; i < ans.size(); i++){
cout << ans[i] << (i < ans.size() - 1 ? " " : ""); // 添加空格以分隔单词
}
return 0;
}
1011 A+B 和 C
这里数据范围不会爆long long,如果再大点就需要用高精度加法
还需要注意负数绝对值大的反而小
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t; cin >> t;
for(int i = 1; i <= t; i++){
ll a, b, c; cin >> a >> b >> c;
if(a + b < 0 && c < 0){
if(abs(a + b) < abs(c))
printf("Case #%d: true\n",i);
else printf("Case #%d: false\n",i);
}else{
if((a + b) > c)
printf("Case #%d: true\n",i);
else printf("Case #%d: false\n",i);
}
}
return 0;
}
坑人的点!!!就是范为10^4是质数的范围,所以我们的N要足够大才行,不然测试点4过不了!
首先获得质数表(运用埃氏筛选法)-> 通过查表获得pm~pn之间的质数
#include <bits/stdc++.h>
using namespace std;
const int N = 200100; // 素数数组的最大长度
bool st[N];
int prime[N], cnt;
void get_prime() {
for (int i = 2; i <= N; i++) {
if (!st[i]) {
prime[cnt++] = i;
for (int j = i + i; j <= N; j += i) {
st[j] = true;
}
}
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
get_prime();
int m, n;
cin >> m >> n;
int count = 0;
for (int i = m - 1; i < n; i++) { // 从 m - 1 开始,因为 prime 的索引从 0 开始
cout << prime[i];
count++;
// 判断是否需要换行
if (count % 10 == 0 || i == n - 1) {
cout << '\n';
} else {
cout << " "; // 如果不是最后一个数字,输出空格
}
}
return 0;
}
总结:题目的理解还需要加强,代码尽量减少bug的出现,例如,重置临时变量