数组操作
//求绝对值差最小
#define min(x, y) (x < y ? x : y)//宏定义一个函数:以别人为参照点,给出自己的学习方法和学习进度
int main()
{
int minmum = INT_MAX,idx_a = 0, idx_b = 0;
int a[10] = { 10,20,30,40,50,60,70,80,98,100 };
int b[5] = { 1,3,5,7,100 };
while (idx_a < 10 && idx_b < 5)
if (a[idx_a] > b[idx_b]) ///绝对值最小的差,在程序中体现为用两个循环来理解
{
int d = a[idx_a] - b[idx_b];
minmum = min(minmum, d);
idx_b++;
}
else
{
int d = b[idx_b] - a[idx_a];
minmum = min(minmum, d);
idx_a++;
}
cout << minmum << endl;
return 0;
}
//逝去天数的问题
int main()
{
int days, leap; //days 天数,leap是否闰年
int y, m, d;
while ((cin >> days) && days != -1) //输出即计入
{
d = days % 7; // for(y = 2000; ; y++)是星期几
for (y = 2000; ; y++)//终止条件不给出的话,循环里自添加break
{
leap = ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0);//日历题目的闰年常用(用leap定义上)
if (days >= year[leap])
days -= year[leap];
else break;
}
for (m = 0; days >= month[leap][m]; m++)
days -= month[leap][m];
cout << y << '-' << setw(2) << setfill('0') << m + 1 << '-'
<< setw(2) << setfill('0') << (days + 1) << ' '
<< week[d] << endl; //自动填充:功能记住!!//字符数组,直接可以用第d行的字符
}
return 0;
约瑟夫(递归)
#include<stdio.h>
#include<iostream>
using namespace std;
int F(int n, int m) {
return n == 1 ? 0 : (F(n - 1, m) + m) % n;
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
cout << F(n, m) << endl;
return 0;
}//上述为递归式子,难以运行大型运算
大整数减法
//大整数减法
//注意如果是
#include<iostream>
#include<string.h>
#include<stdio.h>
const int N = 100;
using namespace std;
int main() {
int n;
cin >> n;
int a[100];
int sum = 0;
for (int i = 0; i < n; i++) {
scanf_s("%d", &a[i]);
//cout << a[i] /70 + 1<<endl;
if (a[i] % 70 != 0) {
sum = sum + (a[i] / 70 + 1);
}
else sum = sum + a[i] / 70;
}//凡是取余运算,考虑要周全
cout << sum * 0.1;
return 0;
}
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
bool cmp(int a, int b) {
return a > b;
}
const int N = 100;
using namespace std;
int main() {
int i;
int a[N];
int n;
while (scanf_s("%d",&n)!=0){//输入非空
if (n != 0) {
i = 1;
cin.get();
scanf_s("%d", &a[0]);
while (cin.get() != '\n')
scanf_s("%d", &a[i++]);
sort(a, a + n, cmp);//sort搭配cmp简化运算
if (n % 2 == 0) {
cout << a[n / 2 - 1] << endl;
memset(a, 0, sizeof(a));
}
else
{
cout << a[n / 2] << endl;//注意还要进行数组的清空
memset(a, 0, sizeof(a));
}
}
else break;
}
return 0;
}
碱基配对
//碱基配对
#include<iostream>
#include<string>
#include<stdio.h>
using namespace std;
int main() {
int n;
cin >> n;//实际如果进入状态的话,15min一道不是问题。所以不必看时间,就是专注做,深入思考
while(n) {//如果more linesneeded 说明是最后一个没有输出,果断用n++来解决问题
char str1[255];
cin.getline(str1, 256);
for (int j = 0; (str1[j] != '\0'); j++) {
switch (str1[j]) {
case'A': {cout << 'T'; break; }
case 'T': {cout << 'A'; break; }
case 'C': {cout << 'G'; break;}
case'G':{cout << 'C'; break;}
}
}cout << endl;
memset(str1, 0, sizeof(str1));
n--;
}return 0;
}
矩阵乘法
//矩阵乘法
#include<iostream>
#include<stdio.h>
using namespace std;
const int N = 1000;
int R1[N][N], R2[N][N], ans[N][N];
int main() {
int a, b, c;
cin >> a >> b >> c;
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++)
{
cin >> R1[i][j];
}
}//录入第一个二维数组(矩阵
for (int i = 0; i < b; i++) {
for (int j = 0; j < c; j++)
{
cin >> R2[i][j];
}
}//录入第二个矩阵
for (int i = 0; i < a; i++)
{
for (int j = 0; j < c; j++)
{
for (int k = 0; k < b; k++)
{
ans[i][j] += R1[i][k] * R2[k][j];
}
}
}//计算矩阵乘法,注意是每个元素相加
for (int i = 0; i < a; i++)
{
cout << ans[i][0];//一个数据出错直接导致结果跳出?为什么呀,因为正好c=1,所以其实输出了第二列都是0
for (int j = 1; j < c; j++)
{
cout << " " << ans[i][j];
}
cout << endl;//输出结果矩阵,注意换行和空格的细节
}
return 0;
不吉利日期
不吉利日期
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
int m[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
int w;
cin >> w;
if ((w + 12) % 7 == 5)
cout << 1 << endl;//单独枚举一月
for (int i = 0; i < 11; i++)//其实用不到第12个月
{
int month = 0;
for (int j = 0; j <= i; j++) {
month = month + m[j];//求出已经过了多少天//j=0也有计算,所以就是说,其实最后一个月是没必要的
}
if ((month +w+12) % 7 == 5)//注意算法中加12天到13号
cout << i + 2 << endl;//日期进位一定要想清楚
}
return 0;
//所过的天数加上w模7等于5即可
}
相关月
//相关月
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
int y1[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
int y2[] = { 31,29,31,30,31,30,31,31,30,31,30,31 };
int y, m1, m2,n;//两个月份大小关系不一定
cin >> n;
int y_[5000] = { 0 };
int m1_[5000] = { 0 };
int m2_[5000] = { 0 };
for (int i = 0; i < n; i++) {
cin >> y_[i]>>m1_[i]>>m2_[i];
}
for (int i = 0; i < n; i++)
{
int y = y_[i];
int m1 = m1_[i];
int m2 = m2_[i];//表达式必须包含指向对象的指针类型=一般就是数组命名和变量命名重复了
if ((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0))//闰年
{
int a = m1 < m2 ? m1 : m2;
int b = m1 < m2 ? m2 : m1;//不能直接用m1,m2会跑错
int sum = 0;
for (int j = a - 1; j < b - 1; j++)
sum =sum+ y2[j];
if (sum % 7 == 0)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
else
{
int y = y_[i];
int m1 = m1_[i];
int m2 = m2_[i];
int a = m1 < m2 ? m1 : m2;
int b= m1 < m2 ? m2 : m1;
int sum = 0;
for (int j = a - 1; j < b - 1; j++)
sum = sum+y1[j];
if (sum % 7 == 0)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}return 0;
}
阶乘之和
阶乘之和
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
long long sum = 0;
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
int s = 1;
for (int j = 1; j <= i; j++)
s = s * j;
sum = sum + s;
}cout << sum << endl;
return 0;
}
斐波那契数列
//斐波那契数列啊原来是
#include<iostream>
#include<stdio.h>
using namespace std;
long long F(int n){
if (n == 1||n==2)
return 1;
else
return F(n - 1) + F(n - 2);
}//命名斐波那契数列
int main() {
int n;
cin >> n;
double sum = 0;
for (int i = 1; i <= n; i++) {
double a=F(i + 2);
double b=F(i + 1);
double c = a/b;
sum = sum + c;
}
printf("%.4lf\n", sum);
return 0;
}
陶陶摘苹果
//陶陶摘苹果
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
int n[11] = { 0 };//数组要开大一点防止越界(其实一般是最后一位越界)
for (int i = 0; i < 10; i++)
{
cin >> n[i];
}//循环输入,依次录入数组
int x;
cin >> x;
int sum = 0;
for (int i = 0; i < 10; i++)
{
if ((x + 30) >= n[i])
sum += 1;
}cout << sum << endl;
return 0;
}
跳绳游戏
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int m;
cin >> m;
if (m == 0)
cout << 60 << endl;
else {
int a[10000] = { 0 };//不建议用new新开一个数组,直接int a[1000]就可以,new 的话还得delete否则会有内存泄露
for (int j = 0; j < m; j++) {
cin >> a[j];
}
//开始判断;首先判断根本就没有跳超的人
if ((a[m - 1] + (m - 1) * 3) <= 60)
{
int q = a[m - 1] + (m - 1) * 3;
if ((60 - q) > 3)
cout << 60 - (m) * 3 << endl;
else//多种情况需要考虑周全,即使是不合规的中断数据,也要同样判断尾列是否超标
cout << a[m - 1] << endl;
}//下面需分设分支判断
//最后一个也没有超的人,直接跳到最后的人
else//再判断最后一个数据超时的人
{
for (int k = 0; k < m - 1; k++) {
int c = a[k] + k * 3;
if ((c < 60) && ((60 - c) <= 3))
cout << a[k] << endl;//在停的过程中结束了比赛
else if ((c < 60) && ((60 - c) > 3))//在中途结束了比赛
{
int d = a[k + 1] + (k + 1) * 3;
if (d < 60)
continue;
else
cout << 60 - (k + 1) * 3 << endl;
}
}
}
}
}return 0;//还有一个问题就是最后差一个才输出
}
自整除数
//自整除数
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
int n;
cin >> n;//看好题目要求
for (int i = 10; i <=n; i++)
{
int a = i % 10;//提取个位
int b = i / 10;//提取十位
if (i%(a + b) == 0)
cout << i << endl;
else
continue;
}
return 0;
}
边界求和限制
边界求和限制
#include<iostream>
#include<stdio.h>
using namespace std;
const int N = 100;
int R[N][N];
int main() {
int k;
cin >> k;
for (int i = 0; i < k; i++) {
int n = 0, m = 0;//初始化
cin >> m >> n;
for (int a = 0; a < N; a++)
for (int b = 0; b < N; b++)
R[a][b] = 0;
for (int a = 0; a < m; a++)
for (int b = 0; b < n; b++)
cin >> R[a][b];
int sum = 0;//完成初始化
if ((m < 3) && (n < 3)) {
for (int a = 0; a < m; a++)
for (int b = 0; b < n; b++)
sum = sum + R[a][b];
cout << sum << endl;
}
else {
for (int a = 1; a < m - 1; a++)
sum = sum + R[a][0] + R[a][n - 1];
for (int b = 0; b < n; b++)
{
sum = sum + R[0][b] + R[m - 1][b];//要考虑到有一行为0 的情况
}
cout << sum << endl;
}
}return 0;
一种等价类划分
//一种等价类划分
#include<iostream>
#include<stdio.h>
using namespace std;
//先定义出取位函数
int f(int n) {
int sum = 0;
while (n != 0) {
sum += n % 10;
n /= 10;
}return sum;
}
int main()
{
int n, m, k;
char c;//输入有逗号,直接定义一个char变量把它吃掉就好
cin >> m >> c >> n >> c >> k;
for (int i = k; i < 40; i += k) {
//子主要程序是对整除的判断
bool first = 1;
for (int j = m + 1; j < n; j++) {
if (f(j)==i)
{//如果是第一位就输出,如果不是第一位输出逗号
if (first)//学习用循环进行第一行的输出
{
if (i == k)//为什么判断条件是i=k,啊不对,是第一行不必要换行,但其他行需要,所以单独处理第一行
cout << j;
else
cout << endl << j;//第一行数据前要输出一个换行
first = 0;
}
else
cout << "," << j;//完成合理的输出,重新进入循环,要输出第一个数,先判断是否是对应的k
}
}
}
return 0;
判断凸四边形
//判断四边形
//用叉乘公式即可:依次判断
#include<iostream>
#include<stdio.h>
using namespace std;
double det(int a, int b, int c, int d) {
return (double)a*d - (double)b*c;
}
int main() {
int x1, x2, x3, x4, y1, y2, y3, y4;
while (cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4)
//依次相邻同向都成立,就是同号相乘大于0
{
if (det(x2 - x1, y2 - y1, x3 - x2, y3 - y2)*det(x3 - x2, y3 - y2, x4 - x3, y4 - y3) > 0) {
if (det(x3 - x2, y3 - y2, x4 - x3, y4 - y3)*det(x4 - x3, y4 - y3, x1 - x4, y1 - y4) > 0) {
if (det(x4 - x3, y4 - y3, x1 - x4, y1 - y4)*det(x1 - x4, y1 - y4, x2 - x1, y2 - y1) > 0)
{//相邻依次判断,必须相邻两个同号才能保证每两个都同号
cout << "yes" << endl;
continue;
}
}
}cout << "no" << endl;
}
return 0;
}
字符串拼接
//字符串拼接
#include<iostream>
#include<string>
using namespace std;
int main() {
char str1[40], str2[40];
int len1, len2;
cin.getline(str1, 20);
cin.getline(str2, 20);
for (len1 = 0; str1[len1] != 0; len1++);
for (len2 = 0; str2[len2] != 0; len2++);
if (len1 >= len2) {
for (len2 = 0; str2[len2] !='\0'; len2++)
str1[len1++] = str2[len2];
str1[len1] = '\0';
}
else {
for (len1 = 0; str1[len1] != '\0'; len1++)
str2[len2++] = str1[len1];
str2[len2] = '\0';
}
cout << str1 << endl;
cout << str2 << endl;
return 0;
}
违禁车牌号
违禁车牌号
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int main() {
char buf[5];
for (int i = 32; i <= 99; i++) {
int n = i * i;
_itoa_s(n, buf, 10);//_itoa_s用这个更安全xs
if (buf[0] < buf[1] && buf[1] < buf[2] && buf[2] < buf[3])
cout << n << endl;
}return 0;
18.字符数比较
//字符数比较
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
int a;
scanf_s("%d", &a);
for(int k=0;k<a;k++) {
char str[1001];
cin.get();//把换行吃掉
cin.getline(str, 1001);
int num[28] = {};
for (int i = 0; str[i] != '\0'; i++) {
for (int s = 97; s <= 97+26; s++) {
char s_ = s;
if (str[i] == s_)
num[s - 97]++;//a的ascII码是97
}
}
int maxnum = num[0];
int symbol=0;
for (int i = 0; i < 28; i++) {
if (num[i] > maxnum) {
maxnum = num[i];
symbol = i;
}
}
int x = symbol + 97;
printf("%c %d\n",x, maxnum);
}return 0;
}
19.字符串匹配算法
//字符串匹配算法
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int main(){
char str1[101], str2[101];
cin.getline(str1, 101);
cin.getline(str2, 101);
int l1 = strlen(str1);
int l2 = strlen(str2);
int flag;
int count = 0;
if (l2 >= l1) {
for (int i = 0; i <= l2 - l1; i++) {//注意最后必须取等,否则无法验证最后一个,而且只有一个字符也过不了
flag = 1;
for (int j = 0; j < l1; j++) {
if (str1[j] != str2[i + j]) {
flag = 0; break;//有点像计算子串
}
}
if (flag)count++;
}
if (count != 0)printf("%s is substring of %s\n", str1, str2);
else cout << "No substring" << endl;
}
else {
for (int i = 0; i <= l1 - l2; i++) {
flag = 1;
for (int j = 0; j < l2; j++) {
if (str2[j] != str1[i + j]) {
flag = 0; break;
}
}
if (flag)count++;
}
if (count != 0)printf("%s is substring of %s\n", str2, str1);
else cout << "No substring" << endl;
}return 0;
}
20.字符串比较
//字符串比较
#include<iostream>
#include<cstring>
using namespace std;
int main() {
char str1[81], str2[81];
cin.getline(str1, 81);
//cin.get();不应该加cin.get,因为cin.getline 自动到换行停止
cin.getline(str2, 81);
int flag = 1;
for (int i = 0; (str1[i] != '\0') && (str2[i] != '\0'); ++i) {//循环条件限制
if (str1[i] <= 90 && str1[i] >= 65)
str1[i] = str1[i] + 32;
if (str2[i] <= 90 && str2[i] >= 65)
str2[i] = str2[i] + 32;//还是先进行一波大小写转化更带感hh,65-90A-Z
if (str1[i] == str2[i])//注意等号和双等号区别
continue;
else if (str1[i] > str2[i]){
cout << ">" << endl;
flag = 0;//a是97
break;
}
else if (str1[i] < str2[i]) {
cout << "<" << endl;
flag = 0;
break;//break和continue的区分用好
}
}
if (flag == 1)//flag作为输出标志
cout << "=" << endl;
return 0;
}
21.单词替换
//单词替换:关于程序的优化:可以把替换和输出放在一行,直接比较单词想到定义二维数组?
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main() {
char word[101][101], find[101], get[101];
int i, j;
while (scanf("%s", &word[0]) != EOF) {//确定有第一个输入,一般都是用来验证第一个值
i = 1;
while (cin.get() != '\n') {//第一个输入后是空格,用cin.get吃掉
scanf("%s", &word[i]);//直接输入一个字符串即可,也不用输入第二个参数了,否则就是对应成二维数组的第101列了
i++;//i顺带成为字符串计数工具
}
scanf("%s", &find);
scanf("%s", &get);
if (strcmp(find, word[j]) == 0)//strcmp相等则返回0
printf("%s", get);
else
printf("%s", word[j]);
for (j = 1; j < i; j++) {
if (strcmp(find, word[j]) == 0)//strcmp相等则返回0
printf(" %s", get);
else
printf(" %s", word[j]);
}
}return 0;
}
22.换酒问题
//换酒问题
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
int a, b;
cin >> a >> b;
int sum = b;
while (b >= a) {
sum = sum + b/a;
b = b % a + b / a;
}
cout << sum << endl;
return 0;
}
23.并查集算法
//并查集算法
#include<iostream>
using namespace std;
const int N = 10110;
int p[N];
int find(int x) {
if (p[x] != x)p[x] = find(p[x]);
return p[x];
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n;i++)
p[i] = i;
while (m--) {
int a = 0, b = 0;
char temp[2];
cin >> temp[0];
if (temp[0] == 'M') {
cin >> a >> b;
p[find(a)] = find(b);//让父节点相同,都等于对应的父节点
}
else {
cin >> a >> b;
if (find(a) == find(b)) {
cout << "Yes" << endl;
}
else cout << "No" << endl;
}
}return 0;
}
24.最匹配的矩阵
//最匹配的矩阵
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
const int N = 101;
int main() {
int j1[N][N], j2[N][N];
int m, n;
cin >> m >> n;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> j1[i][j];
}
}
int r, s;
cin >> r >> s;
for (int i = 0; i < r; i++) {
for (int j = 0; j < s; j++) {
cin >> j2[i][j];
}
}
int flag1 = 0, flag2 = 0;
int sum = 10000000;//sum要开大一点,否则数据太难堪
for (int p = 0; p < m - r + 1; p++) {
for (int q = 0; q < n - s + 1; q++) {//注意p、q是嵌套的,才能逐步更新
int temp = 0;
for (int i = p; i < p + r; i++) {//这两个循环是计算绝对值之和带来的
for (int j = q; j < q + s; j++) {
temp = temp + abs(j1[i][j] - j2[i - p][j - q]);
}
}
flag1 = temp < sum ? p : flag1;
flag2 = temp < sum ? q : flag2;
sum = temp < sum ? temp : sum;//不能放在前面执行,否则sum已经改变,flag12永远变不了
}
}
for (int i = flag1; i < flag1 + r; i++) {
for (int j = flag2; j < flag2 + s; j++) {
cout << j1[i][j] << " ";
}
cout << endl;//矩阵输出换行操作必须
}return 0;
}
25.小茗同学很方
小茗同学很方
#include<iostream>
using namespace std;
const int N = 10000;
int main() {
bool a[N] = { 0 };
int n, m, i, f = 0, t = 0, s = 0;
int k;
scanf("%d,%d,%d", &n, &m, &k);
do {//do,while相当于先开始了一步报数过程
++t;//先加一再操作,相当于指针先移到下一个人,然后判断这个人是否死亡
if (t > n)
t = 1;//好家伙移超了直接归1,连数组的序号都不用考虑了,真的nb;
if (!a[t])
s++;
if (s == m) {
s = 0;
a[t] = 1;
f++;
}
} while (f != k);//把k改成n就是约瑟夫问题的正解
cout << t << endl;
return 0;
26.过河问题
过河问题:双策略:让次大带着大的过,次大回来,重复进入判断;或者让最小带着最大过,然后回来重复进入判断
贪心算法//其实是对那两个人怎么过来进行讨论,
#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
const int N = 1020;
int main() {
int t;
cin >> t;
int a[N] = {};
while (t--) {
int n = 0;
int sum = 0;
cin >> n;
int ans = 0;
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a, a + n);
if (n == 1)
cout << a[0] << endl;
if (n == 2)
cout << a[1] << endl;
if (n == 3)
cout << a[0] + a[1] + a[2] << endl;
while (n > 3) {
ans = min(2 * a[1] + a[n - 1] + a[0], a[n - 1] + a[n - 2] + 2 * a[0]);
sum = sum + ans;
n = n - 2;
if (n == 3) {
cout << sum + a[0] + a[1] + a[2] << endl;
break;
}
if (n == 2) {
cout << sum + a[1] << endl;
break;
}
}
}return 0;
}
27.读天书
//读天书
#include<iostream>
#include<stdio.h>
using namespace std;
const int N = 100010;
int a[N];
int flag[N];
void find(int x) {
if (flag[x] == 0) {
flag[x] = 1;
find(a[x]);
}//弱化并查集算法, 并且学会怎么操作数组元素,只需要把数组在函数声明前定义即可
}
int F(int n) {
int j = 0;
for (int i_ = 1; i_ <= n; i_++)
cin >> a[i_];
for (int i = 1; i <= n; i++) {
if (flag[i] == 0) {
flag[i] = 1;
j++;
}
if (flag[a[i]] == 1)
continue;
else if (flag[a[i]] == 0) {
find(a[i]);
//然后判断a[a[i]]的情况
}
}
return j;
}
int main() {
int n;
cin >> n;
cout << F(n) << endl;
return 0;
}
28.日期串问题
日期串问题: strstr函数找到第一次出现的位置,str(父串,子串)-父串,返回在父串中的序号,记得0——》1要加一
#include<iostream>
#include<cstring>
#include<string.h>
char *digit(int num) {
int l = 0;
char *temp = new char[10];
memset(temp, '0', sizeof(char) * 10 - 1);
while (num > 0) {
temp[l++] = num % 10 + '0';
num = num / 10;
}return temp;//返回地址指针
}
char* get_digit(int num)
{
char *ret = new char[10];
memset(ret, '0', sizeof(char) * 10 - 1);
int l = 0;
while (num > 0)
{
ret[l++] = num % 10 + '0';
num /= 10;
}
return ret;
}
using namespace std;
int main() {
const char a[] = "story" ;
const char b[] = "tor" ;
//char ret = strstr(b, a);
cout << strstr(a, b)-a+1 << endl;
return 0;
cout << get_digit(100);
}
29.魔王军队
//需要明白的是魔王军队有多解,但是总有一解是按照我们的想法,从小到遍历,遍历完之后总是其中的一组合理解
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define N 50010
int x[N] = { 0 };
int n=0, R = 0;//用递推函数,把它建立为整体变量
int range(int y) {
int temp = y;
while ((temp < n) && (x[temp] - x[y] <= R)) {
temp++;
}return temp;//找到由此达到的最大距离
}
int main() {
int cnt = 0, l = 0;
while (cin >> R >> n) {
if ((R < 0)&&(n < 0))
return 0;//程序直接终止
for (int i = 0; i < n; i++)
cin >> x[i];
sort(x, x + n);//先从小到大排列
cnt = 0; l = 0;//每次循环都要先初始化一下
while (l < n) {
l = range(range(l) - 1);//这是因为函数会让它达到R后又加1,所以先循环一下;其实这表示了一个环,就是1必须要包含,n也必须要包含,所以先找到包含1的那块石头,在让石头往下走找到右边界,然后下一个数成为新的1
cnt++;
}
cout << cnt << endl;
}return 0;
}
30.解密密码
//解密密码
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int F(char a) {
int temp = a;//-'0'是减去0对应的ascii,在字符数字转化为整数数字才用
if ((temp >= 97) && (temp <= 97 + 26 - 1)) {
temp = temp - 97;
}
else if ((temp >= 65) && (temp <= 65 + 26 - 1)) {
temp = temp - 39;
}return temp;
}//定义加密函数
char Fn(int a) {
char temp = a;
char str;
if ((a >= 0) && (a <= 25)) {
temp = temp + 97;
}
else if ((a >= 26) && (a <= 51)) {
temp = temp + 39;
}
return temp;
}//解码函数
const int N = 1010;
int main() {
char code[N][110];
int a[N][2];
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++)
cin >> a[i][0] >> a[i][1];
for (int i = 1; i <= n; i++) {
cin >> code[i];
}
for (int i = m; i >= 1; i--)//需要把循环倒过来拆解,不能正着拆解
//用a[i][0]加密a[i][1];
{
int j_ = 0;
for (int j = 0; code[a[i][1]][j] != '\0'; j++) {
//key的j_作为衡量
if (code[a[i][0]][j_] == '\0')
j_ = 0;//一旦过界,即可归零,有点像约瑟夫问题的做法
int x = F(code[a[i][0]][j_]);
int z = F(code[a[i][1]][j]);
int y;
if (x <= z) {
y = z - x;//进行加密的分类讨论
code[a[i][1]][j] = Fn(y);
}
else {
y = 52 + z - x;
code[a[i][1]][j] = Fn(y);//逐行比较编码,【i】【0】or【1】表示操作的第i组数列
}
j_++;
}
} for (int i = 1; i <= n; i++) {
cout << code[i] << endl;
}return 0;
}
31.最短前缀
//最短前缀:只要不和其他字符串重复,但是?相同的字符串呢??
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<string>
#include<string.h>
#include<sstream>
using namespace std;
const int N = 1010;
char str[25];//str是前缀
string s[N];
int main() {
int n = 0;
while (cin >> s[n])n++;
int i, j, k;
for (i = 0; i < n; i++)
{//遍历字符串
for (j = 0; j < s[i].length(); j++) {//先生成前缀
memset(str, 0, sizeof str);
for (k = 0; k <= j; k++) {
str[k] = s[i][k];//生成最短前缀
}
str[k] = '\0';//string最后必须手动加\0
for (k = 0; k < n; k++) {//注意局部变量定义和全局变量定义的矛盾情况
if (k == i)continue;
if (strstr(s[k].c_str(), str) == s[k].c_str())
break;//查是否和别人重复
}
if (k == n) {
cout << s[i] << ' ' << str << endl;//str可以直接输出??
break;//找到后直接输出
}
}
if (j == s[i].length())
cout << s[i] << ' ' << s[i] << endl;
}return 0;
}