7-1 好数 暴力
""a<b 按照 a^2+a*b+b^2"" 由题意可得 a<b 且a*a<t 不可能等于 因为等于的时候解出来a*b为负数 按照a从1到a*a<t的 和 b=a+1起始到b*b<t 开始暴力 找到就输出 如果没有输出过就代表t不是好数 然后转向求大于t的最小好数 然后求该数的每一个来源 跟上面格式相同
#include<bits/stdc++.h>
using namespace std;
int main(void) {
int n, t;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> t;
bool f = 1;
for (int a = 1; a * a < t; ++a)
for (int b = a + 1; b * b < t; ++b)
if (a * a + a * b + b * b == t) {
if (f) {
printf("Yes\n");
f = 0;
}
printf("%d %d\n", a, b);
}
if (f) {
bool F = 0;
printf("No ");
for (++t;; ++t) {
for (int a = 1; a * a < t; ++a) {
for (int b = a + 1; b * b < t; ++b) {
if (a * a + a * b + b * b == t) {
F = 1;
printf("%d\n", t);
for (int a1 = 1; a1 * a1 < t; ++a1)
for (int b2 = a1+1; b2 * b2 < t; ++b2)
if (a1 * a1 + a1 * b2 + b2 * b2 == t) printf("%d %d\n", a1, b2);
break;
}
}
if (F) break;
}
if (F) break;
}
}
}
return 0;
}
7-2 数以类聚 map容器
""输出 N 个给定的整数可以归类的数量、以及规模最大的类中最小的乘积"" 用map容器进行归类
max代表最大分类数量 num代表最大分类中最小的数
#include<bits/stdc++.h>
using namespace std;
int main(void) {
int n, t, max = 0, num = 10000000;
cin >> n;
map<int, int> m;
for (int i = 0; i < n; ++i) {
cin >> t;
int sum = 1;
while (t) {
sum *= t % 10;
t /= 10;
}
++m[sum];
if (m[sum] > max) {
max = m[sum];
num = sum;
}
if (m[sum] == max && sum < num)
num = sum;
}
printf("%d %d", m.size(), num);
return 0;
}
7-3 自定义判题程序 字符串处理
- 如果这个字符不变,则在对应位置输出 0
- 如果这个字符被删除,则在对应位置输出 1
- 如果这个字符被改变,则在对应位置输出 2
- 如果这个字符前面或者后面插入了一个字符,则在插入的位置输出 3
思路
先检测是否含有空格 若有则WC 若无则检测是否k等于非数字的数量 若不等于则WC 若等于则开始按照给出的数字对原始字符串进行操作 创建一个指针变量l1指向当前要进行处理的原始字符串的字符下标 len为""描述对初始字符串的每个字符所做的操作:""序列的长度 j从0到len-1开始遍历 j指向当前要对字符串进行操作的数
02330001100022100过程如下:
string b="";
s1: This is a test.
s2: Tom is a cat.
此时l1为T , 此时给出的处理数字为j指向0 , 0保留T b.push_back(s1[l1++]) ,, l1记得++ 代表当前字符已经处理完毕 要换到下一个字符进行处理 , 同时j++
此时l1为h 此时j指向2 2代表改变,则h变成o 为什么是变o呢? 因为当前b为"T" (因为上一轮刚入了一个T) 接下来对照目标字符串""Tom is a cat."" T后面应是o 所以h变o 那代码怎么写呢?
b.push_back(s2[b.length()]); 此时j++ l1++ 开始处理下一个字符
此时l1指向字符i 此时j指向3 3代表这个位置添加了一个字符 那我们就添加一个字符,代码如下
b.push_back(s2[b.length()]); 发现是不是跟上文代码一致? 因为现在b="To" 对照目标字符串 ""Tom is a cat."" 此时应该写入m,,所以写入m 加入字符完毕后j需要++吗? 需要因为当前指令已经处理完毕 l1需要++吗?大可不需要!!!因为l1对应的字符i不是0(保留)不是2(修改)不是1(丢弃)而是3(前面加了字符) 只是前面加上了字符 自己还没有被处理
此时 l1指向字符i 因为上次没有对字符i进行处理只是在其前面加上了字符 其本身还没有进行任何处理 然后此时j指向3 然后又在其前面加上了个空格字符 " " j++
此时l1指向字符i j指向命令0 0为保留则保留i 代码为 b.push_back(s1[l1++]); j++
,,,,,,,,以此类推
注意点:
对于用户输出的 K,如果其操作序列的确给出了 K 步操作并可以完成字符串的变换,则称为一个“可行解”。所谓“正确提交”,是指所有提交的可行解中的最优解。
题目让你输出k最小的可行解 如果一个解的k为10 经过10此处理后原始字符串变成了目标字符串,则代表此k为10的解是一个可行解 但是如果另一个可行解的k为9 9是比10小的,用了更少的步骤得到了目标字符串 则k为9的解成为 正确提交 题目就是让你找k最小的解,对于这些k最小的解(们) 输出AC 其余只要k大于最小k的可行解都要输出WC
#include<bits/stdc++.h>
using namespace std;
int main(void) {
string s1, s2, s;
getline(cin, s1);
getline(cin, s2);
int n, min = -1;
scanf("%d", &n);
getchar();
int a[n], f[n] = {0};
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
getchar();
getline(cin, s);
if (s.find(' ') != string::npos) f[i] = 1;
else {
int c = 0, len = s.length();
for (int j = 0; j < len; ++j)
if (s[j] != '0') ++c;
if (c != a[i]) f[i] = 1;
else {
string b = "";
int l1 = 0;
for (int j = 0; j < len; ++j) {
if (s[j] == '0') {
b.push_back(s1[l1++]);
} else if (s[j] == '1') {
++l1;
} else if (s[j] == '2') {
b.push_back(s2[b.length()]);
++l1;
} else if (s[j] == '3') {
b.push_back(s2[b.length()]);
}
}
if (b == s2) {
if (min == -1) min = a[i];
else if (a[i] < min) min = a[i];
f[i] = 0;
} else {
f[i] = 1;
}
}
}
}
for (int i = 0; i < n; ++i) {
if (!f[i] && a[i] == min) printf("AC\n");
else printf("WA\n");
}
return 0;
}
7-4 数组与链表 前缀和
坑点分析: ""这种结构首先初始化一个长度为 L0 的整型数组 A0,返回给用户使用。""
题目在一开始就告诉你了 先初始化了一个数字A0 代表无论访问合与不合法 最一开始就已经开了一个数组A0 所以在最后输出一共开了多少数组时候? 注意当全部访问为非法时候 , 一共开了1个数组就是最开始初始化的那个 所以不是0是1!!!!!!
#include<bits/stdc++.h>
using namespace std;
int main(void) {
int n, k, t, max = 1;
cin >> n >> k;
int a[n] = {0}, b[n];
for (int i = 0; i < n; ++i) {
cin >> b[i] >> a[i];
if (i == 0) --a[i];
else a[i] += a[i - 1];
}
for (int i = 0; i < k; ++i) {
cin >> t;
if (t >a[n-1]) printf("Illegal Access\n");
else {
int len = 0;
while (len < n && t > a[len])
len++;
if (len + 1 >= max) max = len + 1;
if (len) t -= (a[len - 1] + 1);
printf("%d\n", b[len] + t * sizeof(int));
}
}
printf("%d", max);
return 0;
}
7-5 取帽子 排序
当然这里我没用排序算法,我直接用的map容器 按key值从小到大存储
对帽子序列map存一个 对人序列map存一个 然后再遍历两个map容器建立对应关系
#include<bits/stdc++.h>
using namespace std;
int main(void) {
int n, t;
cin >> n;
int a[n];
map<int, int> m1, m2;
for (int i = 0; i < n; ++i) {
cin >> a[i];
m1[a[i]] = 1;
}
for (int i = 0; i < n; ++i) {
cin >> t;
m2[t] = i + 1;
}
auto a1 = m1.begin();
auto a2 = m2.begin();
for (; a1 != m1.end() && a2 != m2.end(); a1++, a2++)
a1->second = a2->second;
bool f = 1;
for (int i = n - 1; i > -1; --i) {
printf("%s%d", f ? "" : " ", m1[a[i]]);
f = 0;
}
return 0;
}