题目汇总(总结篇)

标题:习题汇总

标题:搜索dfs(复杂度n!)(2021/2/7)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int p[10000];
int q[10000];
intt n = 3;
void dfs(int dep) {
    if (dep > n) {
        for (int i = 1; i <= n; i++) {
            printf("%d ", q[i]);
        }
        printf("\n");
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (!p[i]) {
            p[i] = 1;//标记是否使用过;
            q[dep] = i;//第dep位置的数是i;
            dfs(dep + 1);//判断dep是否为最后一个位置;
            p[i] = 0;
        }
    }
}
int main() {
    dfs(1);
    return 0;
}

/这是搜索dfs深搜的做法;代码核心是结合递归思想先固定第一位在去探索第二位可以是哪些值,
当第二位只要找到了一位,就去找第三位(此时的第三位就是那个剩下的值),当第三位的值全部找完了,
就返回第二位,看第二位是否还有其他可能,重复操作知道程序结束;
/
实现搜索过程中别忘记标记数组,当某个数使用过就记为0,当在这个位置结束时将这个的数重新计为1;

 for (int i = 1; i <= n; i++) {
        if (!p[i]) {
            p[i] = 1;//标记是否使用过;
            q[dep] = i;//第dep位置的数是i;
            dfs(dep + 1);//判断dep是否为最后一个位置;
            p[i] = 0;  //重新使用这位

标题 搜索迷宫简易版(2021/4/17)

牛客

主题是做迷宫来判断是否能走到终点
上代码

#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>

using namespace std;

int dir[10][4] = { {0,0}, {0,-1},{0,1},{-1,0},{1,0} };  //上下左右
int vis[502][505];
int n, m;
char str[502][502];
int sx, sy;
int ex, ey;
int nx, ny;
int cnt;

bool dfs(int x,int y) {
	vis[x][y] = 1;
	for (int i = 1; i <= 4; i++) {
			nx = x + dir[i][0];    // 0 代表x  
			ny = y + dir[i][1];   //  1 代表y	
			if (nx == ex && ny == ey) {
				cnt = 1;
				return true;
			}
			else if (str[nx][ny] != '#' && nx <= n && nx >= 1 && ny <= m && ny >= 1&&!vis[nx][ny]) {
                vis[nx][ny] = 1;
				dfs(nx, ny);		
			}
	}
}
int main() {
	while (cin >> n >> m) {
		cnt = 0;
		memset(vis, 0, sizeof(vis));
		memset(str, 0, sizeof(str));
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				cin >> str[i][j];
				if (str[i][j] == 'S') {
					sx = i;
					sy = j;
				}
				if (str[i][j] == 'E') {
					ex = i;
					ey = j;
				}
			}
		}
		dfs(sx, sy);
		if (cnt) {
			cout << "Yes" << endl;
		}
		else cout << "No" << endl;
	}
	return 0;
}


第一点用数组来记录方向
其实其他的没啥
看看就行

标题 区间dp(2021/2/7)

习题网址
这是个区间dp问题
这个题目对于一个初学者我来讲,感觉是真的不友好,写了快一周才有眉目;首先我认为这个就是说第一个数在选的时候假设选了左边是最佳的情况但第二个数或第三个数会影响它,这岂不是要了老命!!!!!!
唉,还是太菜了了。反复研读代码,最主要是在草稿上演算了一大堆,
还是先上代码在分析吧

#include<stdio.h>
	#include<string.h>
	#include<stdlib.h>
	int p[1005];
	int q[1005];
	int dp[1005][10005];
	int t;
	int n;
	int max_(int x, int y) {
		if (x < y) return y;
		return x;
	}
	int main() {
		scanf("%d", &t);
		while (t--) {
			scanf("%d", &n);
			memset(p, 0, sizeof(p));
			memset(q, 0, sizeof(q));
			memset(dp, 0, sizeof(dp));
			for (int i = 1; i <= n; i++) scanf("%d", &p[i]);
			for (int i = 1; i <= n; i++) scanf("%d", &q[i]);
			for (int i = 1; i <= n; i++) dp[i][i] = p[i] * q[n];
			for (int i = n; i >= 1; i--) {
				for (int j = i + 1; j <= n; j++) {
					dp[i][j] = max_(dp[i + 1][j] + p[i] * q[n-(j-i)], dp[i][j - 1] + p[j] * q[n-(j-i)]);
				}
			}
			printf("%d\n", dp[1][n]);    
		}
		return 0;
	}

先解释一下代码
核心代码:

for (int i = n; i >= 1; i--) {
				for (int j = i + 1; j <= n; j++) {
					dp[i][j] = max_(dp[i + 1][j] + p[i] * q[n-(j-i)], dp[i][j - 1] + p[j] * q[n-(j-i)]);
				}
			}

这是区间dp:之所以叫区间这也是它的特点之一:区间【i,j】是要求的;
这也是我一直在考虑的一个问题;
首先我们来看看正常思路:如果n=4;那么会有2* 2 * 2=8种情况;
也就是2^(n-1)种情况;这种复杂都明显太大;
但是区间dp复杂度是(n^2)级别;
先解释x:
在这里插入图片描述
在这里插入图片描述
x本意就是☞第几个数(b[])去选左右;具体见上图;
然而最大的疑问是难道不会有后效应吗??
这个应该是最难理解的地方,知道大表才发现,原来是在循环的时候就每个数都使用过;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
见上解析

对于区间dp其实还有很多不明白的东西,在日后的学习还是要多多思考

标题B. One Bomb(2021/2/23)

习题网址

题目大意:问是否存在一个炸弹在有墙的牢房中或是在空的牢房中,这没炸弹如果引爆是否有可能能使所有的围墙摧毁,如果可以那么就输出YES并且输出坐标,如果不可以就输出NO;

思路
如果是枚举每一个点的话时间复杂度过高;假设某个坐标符合那么该列和该行就被引爆,那么我们就像一次性能引爆最多的情况是什么?分析其实很简单,想引爆最多数量的墙便是去引爆某一行数量最多和某一列数量最多;
为什么是找最多的呢?其实很好理解,我想爆掉所有的结果当然是最多的,如歌这个点最大值正好就是所有点就说明这个点是对的。
那么就上AC代码吧

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int n, m;
char str[1005][1005];
struct ty {
	int x;
	int y;
};
struct ty p[1005];
int main() {
	while (~scanf("%d%d", &n, &m)) {
		memset(p, 0, sizeof(p));
		memset(str, 0, sizeof(str));
		int maxx = 0;
		int placex = 1;
		int maxy = 0;
		int placey = 1;
		int sumcnt = 0;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				scanf(" %c", &str[i][j]);
				if (str[i][j] == '*') {
					p[i].x++;       //记录第i行有多少个
					sumcnt++;
				}
			}
			if (maxx <= p[i].x) {
				maxx = p[i].x;
				placex = i;
			}
		}
		for (int i = 1; i <= m; i++) {
			for (int j = 1; j <= n; j++) {
				if (str[j][i] == '*') p[i].y++;  //记录第i列有多少个;
			}
			if (maxy <= p[i].y) {
				maxy = p[i].y;
				placey = i;
			}
		}
		int flag = 0;
		for (int i = 1; i <= m; i++) {
			if (str[placex][i] == '*') {
				if (sumcnt == (maxx + p[i].y - 1)) {
					printf("YES\n%d %d", placex, i);
					flag = 1;
					return 0;
				}
			}
			else {
				if (sumcnt == (maxx + p[i].y)) {
					printf("YES\n%d %d", placex, i);
					flag = 1;
					return 0;
				}
			}
		}
		for (int i = 1; i <= n; i++) {
			if (str[i][placey] == '*') {
				if (sumcnt == (maxy + p[i].x - 1)) {
					printf("YES\n%d %d", i, placey);
					flag = 1;
					return 0;
				}
			}
			else {
				if (sumcnt == (maxy + p[i].x)) {
					printf("YES\n%d %d", i, placey);
					flag = 1;
					return 0;
				}
			}
		}
		if (!flag) printf("NO\n");
	}
	return 0;
}
for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				scanf(" %c", &str[i][j]);
				if (str[i][j] == '*') {
					p[i].x++;       //记录第i行有多少个
					sumcnt++;
				}
			}
			if (maxx <= p[i].x) {
				maxx = p[i].x;
				placex = i;
			}
		}
		for (int i = 1; i <= m; i++) {
			for (int j = 1; j <= n; j++) {
				if (str[j][i] == '*') p[i].y++;  //记录第i列有多少个;
			}
			if (maxy <= p[i].y) {
				maxy = p[i].y;
				placey = i;
			}
		}
```在这里记录下每一行有多少个*每一列有多少个*并统计最多的一行最多的一列

for (int i = 1; i <= m; i++) {
			if (str[placex][i] == '*') {
				if (sumcnt == (maxx + p[i].y - 1)) {
					printf("YES\n%d %d", placex, i);
					flag = 1;
					return 0;
				}
			}
			else {
				if (sumcnt == (maxx + p[i].y)) {
					printf("YES\n%d %d", placex, i);
					flag = 1;
					return 0;
				}
			}
		}

遍历最大行从1–m列遍历寻是否有满足的点

for (int i = 1; i <= n; i++) {
			if (str[i][placey] == '*') {
				if (sumcnt == (maxy + p[i].x - 1)) {
					printf("YES\n%d %d", i, placey);
					flag = 1;
					return 0;
				}
			}
			else {
				if (sumcnt == (maxy + p[i].x)) {
					printf("YES\n%d %d", i, placey);
					flag = 1;
					return 0;
				}
			}
		}

遍历最大列从1–n列遍历寻是否有满足的点

标题:rating 赛 B. Beautiful Numbers(2021/2/27)

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a permutation p=[p1,p2,…,pn] of integers from 1 to n. Let’s call the number m (1≤m≤n) beautiful, if there exists two indices l,r (1≤l≤r≤n), such that the numbers [pl,pl+1,…,pr] is a permutation of numbers 1,2,…,m.

For example, let p=[4,5,1,3,2,6]. In this case, the numbers 1,3,5,6 are beautiful and 2,4 are not. It is because:

if l=3 and r=3 we will have a permutation [1] for m=1;
if l=3 and r=5 we will have a permutation [1,3,2] for m=3;
if l=1 and r=5 we will have a permutation [4,5,1,3,2] for m=5;
if l=1 and r=6 we will have a permutation [4,5,1,3,2,6] for m=6;
it is impossible to take some l and r, such that [pl,pl+1,…,pr] is a permutation of numbers 1,2,…,m for m=2 and for m=4.
You are given a permutation p=[p1,p2,…,pn]. For all m (1≤m≤n) determine if it is a beautiful number or not.

Input
The first line contains the only integer t (1≤t≤1000) — the number of test cases in the input. The next lines contain the description of test cases.

The first line of a test case contains a number n (1≤n≤2⋅105) — the length of the given permutation p. The next line contains n integers p1,p2,…,pn (1≤pi≤n, all pi are different) — the given permutation p.

It is guaranteed, that the sum of n from all test cases in the input doesn’t exceed 2⋅105.

Output
Print t lines — the answers to test cases in the order they are given in the input.

The answer to a test case is the string of length n, there the i-th character is equal to 1 if i is a beautiful number and is equal to 0 if i is not a beautiful number.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
struct ty {
	int val;
	int pos;
};
struct ty p[200005];
int t;
int n;
int cmp(const void* a, const void* b) {
	return ((struct ty*)a)->val - ((struct ty*)b)->val;
}
int max_(int x, int y) {
	if (x < y) return y;
	return x;
}
int min_(int x, int y) {
	if (x > y) return y;
	return x;
}
int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) {
			scanf("%d", &p[i].val);
			p[i].pos = i;
		}
		qsort(&p[1], n, sizeof(p[1]), cmp);
		printf("1");
		int max = p[1].pos;
		int min = p[1].pos;
		for (int i = 2; i <= n; i++) {
			max =max_ (max, p[i].pos);
			min =min_ (min, p[i].pos);
			if (max - min + 1 == i) printf("1");
			else printf("0");
		}
		printf("\n");
	}
	return 0;
}

标题:B g2g c u l8r(2021/3/14)

题目大意:给一个数字N;接下来有n行;每一行的第一个字母或单词是后面的索引;
再给一个数字m,代表接下来有m行再给出的单词或字母出现过索引就用这个索引后的来替代:
这个用map来存会比较好:

#include<iostream>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>

using namespace std;

int n;
int m;

map<string, string>p1;
map<string, int >p2;

string s1, s2;
int main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> s1;
        getchar();
		getline(cin, s2);
		p1[s1] = s2;
		p2[s1] = 1;
	}
	cin >> m;
	char ch;
	for (int i = 0; i < m; i++) {
		ch = '1';
		string s3;
		while (ch != '\n') {
			cin >> s3;
			ch = getchar();
			if (p2[s3] == 1) cout << p1[s3] << " ";
			else cout << s3 << " ";
		}
		cout << endl;
	}
	return 0;
}


标题:CTip to be Palindrome(2021/3/14)

这题比较简单:主要大意是:巨款吃大餐给小费;但是小非如果不是整数就向上取整;
但后应付小费总和如果不是回文数就加到最近的一个回文数:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
 
int n;
double num;
double tip;
double sum;
int p[13005];
int q[13005];
int temp1;
int temp2;
int temp3;
int cnt;
void init() {
    for (int i = 1; i <= 13000; i++) {
        temp3 = i;
        temp2 = temp1 = 0;
        while (temp3) {
            temp1 = temp3 % 10;
            temp2 = temp2 * 10 + temp1;
            temp3 /= 10;
        }
        if (temp2 == i) {
            q[++cnt] = i;
        }
    }
}
int f(int x) {
    init();
    for (int i = 1; x >= q[i]; i++) {
        if (q[i] == x) return 1;
    }
        return 0;
}
 
int main() {
 
    init();
    scanf("%d", &n);
    while (n--) {
        scanf("%lf", &num);
        tip = (num * 0.2);
        int a = (int)(tip);
        if (tip > a) a++;
        sum = num + a;
        int t = (int)(sum);
        if (f(t)) {
            printf("Input cost: %.0f\n", num);
            printf("%.0f %.0f\n", sum - num, sum);
        }
        else {
            for (int i = 1;; i++) {
                if (q[i] >= sum) {
                    sum = q[i];
                    break;
                }
            }
            printf("Input cost: %.0f\n", num);
            printf("%.0f %.0f\n", sum - num, sum);
        }
        printf("\n");
 
    }
 
    return 0;
}

这样写有点复杂主要是在浮点型和整形之间转换:
但是可以用户ceil()向上取整函数;

tip = (num * 0.2);
        int a = (int)(tip);
        if (tip > a) a++;
改写成:
tip = ceil(num*0.2);

标题: All the Vowels Please(2021/3/5)

B. All the Vowels Please
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Tom loves vowels, and he likes long words with many vowels. His favorite words are vowelly words. We say a word of length k is vowelly if there are positive integers n and m such that n⋅m=k and when the word is written by using n rows and m columns (the first row is filled first, then the second and so on, with each row filled from left to right), every vowel of the English alphabet appears at least once in every row and every column.

You are given an integer k and you must either print a vowelly word of length k or print −1 if no such word exists.

In this problem the vowels of the English alphabet are ‘a’, ‘e’, ‘i’, ‘o’ ,‘u’.

Input
Input consists of a single line containing the integer k (1≤k≤104) — the required length.

Output
The output must consist of a single line, consisting of a vowelly word of length k consisting of lowercase English letters if it exists or −1 if it does not.

If there are multiple possible words, you may output any of them.

Examples
inputCopy
7
outputCopy
-1
inputCopy
36
outputCopy
agoeuioaeiruuimaeoieauoweouoiaouimae
Note
In the second example, the word “agoeuioaeiruuimaeoieauoweouoiaouimae” can be arranged into the following 6×6 grid:
在这里插入图片描述
It is easy to verify that every row and every column contain all the vowels.

题目大意:要求给出的一个k,存在n*m=k;并且在每行每列五个元音字母同时出现:

这个关键在于,找出5*5满足这个条件,当5 * 5满足数每一列就复制第一例中的字母,每一行就复制第一行的字母;
代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int n;
char str[205][2005];
int x, y;
int flag;
int main() {
	scanf("%d", &n);
	if (n < 25) {
		printf("-1\n");
		return 0;
	}
	for (int i = 5; i <= sqrt(n); i++) {
		if (n % i == 0) {
			x = i;
			y = n / i;
			flag = 1;
			break;
		}
	}
	if (!flag) {
			printf("-1\n");
			return 0;
		}
	char str6[6][6] = { {" "}, {" aeiou"} ,{" eioua"}, {" iouae"},{" ouaei"}, {" uaeio"} };
	if (n == 25) {
		printf("aeioueiouaiouaeouaeiuaeio");
		return 0;
	}
	for (int i = 1; i <= 5; i++) {
		for (int j = 1; j <= 5; j++) {
			str[i][j] = str6[i][j];
		}
	}
	for (int i = 1; i <= 5; i++) {
		for (int j = 6; j <= y; j++) {
			str[i][j] = str[i][1];
		}
	}
	for (int i = 6; i <= x; i++) {
		for (int j = 1; j <= y; j++) {
			str[i][j] = str[1][j];
		}
	}
	for (int i = 1; i <= x; i++) {
		for (int j = 1; j <= y; j++) {
			printf("%c", str[i][j]);
		}
	}
	return 0;
}

1.首先判断这个n是否小于25;
若小于必不可能成立

if (n < 25) {
		printf("-1\n");
		return 0;
	}

2.判断这个n是否能被分解成2个都大于或等于五的数

for (int i = 5; i <= sqrt(n); i++) {
		if (n % i == 0) {
			x = i;
			y = n / i;
			flag = 1;
			break;
		}
	}
	if (!flag) {
			printf("-1\n");
			return 0;
		}

如果可以就是取最小的一个(为了方便省事)

char str6[6][6] = { {" "}, {" aeiou"} ,{" eioua"}, {" iouae"},{" ouaei"}, {" uaeio"} };
	if (n == 25) {
		printf("aeioueiouaiouaeouaeiuaeio");
		return 0;
	}
	for (int i = 1; i <= 5; i++) {
		for (int j = 1; j <= 5; j++) {
			str[i][j] = str6[i][j];
		}
	}

把这些元音的字母存入进去

for (int i = 1; i <= 5; i++) {
		for (int j = 6; j <= y; j++) {
			str[i][j] = str[i][1];
		}
	}

把5列以外的所有位置都存上每一行的第一个子母;

for (int i = 1; i <= x; i++) {
		for (int j = 1; j <= y; j++) {
			printf("%c", str[i][j]);
		}
	}

把超过5行的每一行都一第一行的字母打出出来;

继续补提拔:实在太菜

题意很简单:就是每两个数的gcd()不为1;
并且不存在a%b==0;

这个其实打个表就好了;
但是就是感觉怪怪的

从后往前数:

#include<iostream>
#include<string>
#include<cstring>

using namespace std;

int main() {
	
	int t;
	int cnt;
	cin >> t;
	while (t--) {
		int x;
		cnt = 0;
		cin >> x;
		for (int i = 4 * x; i >= 2; i -= 2) {
			cnt++;
			if (cnt == x) {
				cout << i << endl;
				break;
			}
			cout << i << " ";
		}
	}

	return 0;
}

每个数-2,这样就可以保证题目中的两个条件;

标题:3n+1(2021/3/3)

题目网址
简述标题大意:给一个数,如果这个数是偶数的话,那么将这个数除以二,如果是奇数的话,就将这个数乘以3加上1;当这个数为1是就结束;
具体例子:n = 22: 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
而问题是i,j当中所有数当中的最长长都为多少?
上AC代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
long long int n;
long long int p[1000005];
long long int a, b;
void pre() {
	p[1] = 1;
	for (long long int i = 2; i <= 500000; i++) {
		long long int temp = i;
		p[i] = 1;
		while (temp != 1) {
			if (temp % 2 == 0) temp /= 2;
			else temp = temp * 3 + 1;
			if (temp < i) {
				p[i] += p[temp];
				break;
			}
			p[i]++;
		}
	}
	for (long long int i = 500001; i <= 1000005; i++) {
		long long  int temp1 = i;
		p[i] = 1;
		while (temp1 != 1) {
			if (temp1 % 2 == 0) temp1 /= 2;
			else temp1 = temp1 * 3 + 1;
			if (temp1 < i) {
				p[i] += p[temp1];
				break;
			}
			p[i]++;
		}
	}
}
void swap(int* a, int* b) {
	int temp2=*a;
	*a = *b;
	*b = temp2;
}
int max_(int x, int y) {
	if (x < y) return y;
	return x;
}
int main() {
	pre();
	while (~scanf("%lld%lld", &a, &b)) {
		long long int max = 1;
		if (a > b) {
			swap(&a, &b);
			printf("%lld %lld ", b, a);
		}
		else printf("%lld %lld ", a, b);
		for (int i = a; i <= b; i++)
			 max = max_(max, p[i]);
		printf("%lld\n", max);
	}
	return 0;
}

这个分为如下几部分:
1.先计算出1–1000000当中所有数对应的长度
这里:先声明正常来讲电脑正常来讲可以每秒可以完场10^8条语句,当数据范围是1000000,所以自然数超时,那么我们就可以这个,将1000000分成两部分;这么一来就解决了这个问题;
我认为这是问题的一个亮点所在。
2.第二个亮点是我们其实不用一直将n求到1,我们知道让当前这个n,在变换的过程中得到的某个值小于i(这个i是指第i个数)

void pre() {
	p[1] = 1;
	for (long long int i = 2; i <= 500000; i++) {
		long long int temp = i;
		p[i] = 1;
		while (temp != 1) {
			if (temp % 2 == 0) temp /= 2;
			else temp = temp * 3 + 1;
			if (temp < i) {
				p[i] += p[temp];
				break;
			}
			p[i]++;
		}
	}
	for (long long int i = 500001; i <= 1000005; i++) {
		long long  int temp1 = i;
		p[i] = 1;
		while (temp1 != 1) {
			if (temp1 % 2 == 0) temp1 /= 2;
			else temp1 = temp1 * 3 + 1;
			if (temp1 < i) {
				p[i] += p[temp1];
				break;
			}
			p[i]++;
		}
	}
}

这里最坑是的:i,j,那个大没有说,这个确实没看到
所以有了swap这个函数

大致就是这样。

标题:字符加(int)强制转换(2021/2/28)

1093 字符串A+B (20 分)
给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集。要求先输出 A,再输出 B,但重复的字符必须被剔除。

输入格式:
输入在两行中分别给出 A 和 B,均为长度不超过 10
​6
​​ 的、由可见 ASCII 字符 (即码值为32~126)和空格组成的、由回车标识结束的非空字符串。

输出格式:
在一行中输出题面要求的 A 和 B 的和。

输入样例:
This is a sample test
to show you_How it works
输出样例:
This ampletowyu_Hrk

添加链接描述:一道题的网站
这个题是真的妙:
如果直接暴力的写法:
首先将这两个字符串连在一起;然后遍历一次,可惜最后一个点超时

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
char str1[2000001];
char str2[1000005];
int main() {
	gets(str1);
	gets(str2);	
	strcat(str1, str2);
	int len1 = strlen(str1);
	printf("%c", str1[0]);
	for (int i = 1; i <= len1 - 1; i++) {
		int flag = 0;
		for (int j = 0; j < i; j++) {
			if (str1[i] == str1[j]) {
				flag = 1;	
				break;
			}
		}
		if (!flag) printf("%c", str1[i]);
	}
	return 0;
}

但是换种思路,假设给字符标记,当出现过的字符就标记为1,未出现就标记为0;
但是这里就涉及到一个字符型变量转换成整形—可以加个(int)转换:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
char str1[2000005];
char str2[2000005];
int p[2000005];
int main() {
	gets(str1);
	gets(str2);	
	strcat(str1, str2);
	int len1 = strlen(str1);
	printf("%c", str1[0]);
	p[(int)str1[0]] = 1;
	for (int i = 1; i <= len1 - 1; i++) {
		if (p[(int)str1[i]] != 1) {
			printf("%c", str1[i]);
			p[(int)str1[i]] = 1;
		}
	}
	return 0;
}

这种方法确实是妙,巧妙地将字符转换成整型

标题: 矩阵计算

题目

就是正常思维很简单

#include<iostream>
#include<string>
#include<cmath>

using namespace std;
#define ll long long 

ll n;
int p[205][205];
int q[205][205];
int sum;

int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> p[i][j];
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> q[i][j];
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int l = 1; l <= n; l++) {
			for (int j = 1; j <= n; j++) {
               sum += p[i][j] * q[j][l];
			}
		cout << sum ;
		sum = 0;
		if (l < n) cout << " ";
		}
		if(i<n)
		cout << endl<<endl;
	}
	return 0;
}

标题:吃火锅(天梯赛)

输入格式:
输入每行给出一句不超过 80 个字符的、以回车结尾的朋友信息,信息为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。当读到某一行只有一个英文句点 . 时,输入结束,此行不算在朋友信息里。

输出格式:
首先在一行中输出朋友信息的总条数。然后对朋友的每一行信息,检查其中是否包含 chi1 huo3 guo1,并且统计这样厉害的信息有多少条。在第二行中首先输出第一次出现 chi1 huo3 guo1 的信息是第几条(从 1 开始计数),然后输出这类信息的总条数,其间以一个空格分隔。题目保证输出的所有数字不超过 100。

如果朋友从头到尾都没提 chi1 huo3 guo1 这个关键词,则在第二行输出一个表情 -_-#。

输入样例 1:
Hello!
are you there?
wantta chi1 huo3 guo1?
that’s so li hai le
our story begins from chi1 huo3 guo1 le
.
输出样例 1:
5
3 2
输入样例 2:
Hello!
are you there?
wantta qi huo3 guo1 chi1huo3guo1?
that’s so li hai le
our story begins from ci1 huo4 guo2 le
.
输出样例 2:
5
-_-#

使用strstr函数自动找到目标字串:

char* s = "abc";
	char* w = "abcd";
	char* a = strstr(w, s);
	if (a != NULL) {

	}
	else {

	}

火锅代码:

#include<stdio.h>
	#include<string.h>
	#include<stdlib.h>
	#include<math.h>

	char str1[105];
	char ch;
	int flag1;
	int cnt;
	int f, h;

	int main() {
		while (1) {
			char* p = "chi1 huo3 guo1";
			
			gets(str1);
			h++;
			if (!strcmp(str1,".")) break;
			char * s = strstr(str1, p);
			if (s!=NULL) {
				cnt++;
				if (cnt == 1) f = h;
			}
		}
		printf("%d\n", h - 1);
		if (cnt == 0) {
			printf("-_-#\n");
		}
		else printf("%d %d\n", f, cnt);

		return 0;
	}

另一版本:

	#include<stdio.h>
	#include<string.h>
	#include<stdlib.h>
	#include<math.h>
	
	char str1[105];
	char ch;
	int flag1;
	int cnt;
	int f, h;
	int i, j, temp;
	
	int main() {
		int h = 1;
		char p[14] = "chi1 huo3 guo1";
		gets(str1);
		while (1) {	
			i = j = temp = 0;
			int len = strlen(str1);
			if (len == 1 && str1[0] == '.') break;
			for (i = 0; i < len; i++) {
				temp = i;
				flag1 = 0;
				for (j = 0; j <= 13; j++,i++) {
					if (str1[i]== p[j]) continue;
					else {
						flag1 = 1;
						break;
					}
				}
				if (!flag1) {
					cnt++;
					if (cnt == 1) f = h;
					break;
				}
				j = 0;
				i = temp;
			}
			h++;
			memset(str1, 0, sizeof(char));
			gets(str1);
		}
			printf("%d\n", h - 1);
			if (cnt == 0) {
				printf("-_-#\n");
			}
			else printf("%d %d\n", f, cnt);
		return 0;
	}
	

注意的是只有但 . 单独一行时程序结束这是wa n次的原因;

标题:PTA:海绵城市:

深度优先搜素

#include <iostream>
#include<cstring>

using namespace std;
const int N = 21;

int vis[N][N];
int temp;
int cnt;

bool  test(int a[N][N], int j, int k) {
    cnt++;
    if (cnt == 1) temp = j;
    int i;
    int star;
    star = j;
    for (i = 1; i <= N; i++) {
        if (a[star][i] && !vis[star][i]) {
            if (i == k) {
                memset(vis, 0, sizeof(vis));
                return true;
            }
            vis[star][i] = 1;
            vis[i][star] = 1;
            if (test(a, i, k)) return true;
        }
    }
    if (star == temp) {
        memset(vis, 0, sizeof(vis));
        return false;
    }
    else    return false;
}

int main()
{
    int a[N][N] = { 0 }, n, m, i, j, k;
    cin >> n;
    for (i = 0; i < n; i++) {
        cin >> j >> k;
        a[j][k] = a[k][j] = 1;
    }
    cin >> m;
    for (i = 0; i < m; i++) {
        cin >> j >> k;
        cout << j << '-' << k << ' ';
        if (test(a, j, k)) cout << "connected" << endl; else cout << "disconnected" << endl;
    }
    return 0;
}


标题:codeforces (训练赛)B题题解

大意是 找出 分别符合 女孩 taxi 送外卖的 的人
这个人是 拥有这个电话最多的人

ac代码:

#include<stdio.h>

int n;
int p[105][4];
int num;
char name[20];
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= 4; i++) {
		
		scanf("%d", &num);

		scanf(" %s", name);
		char str1[105][10];
		int g_num = 0;
		int taxi = 0;
		int oth = 0;

		for (int j = 1; j <= num; j++) {

			scanf(" %s", str1[j]);

			if (str1[j][0] == str1[j][1] && str1[j][3] ==
				str1[j][4] && str1[j][6] == str1[j][7] &&
				str1[j][0] == str1[j][3] && str1[j][0] == str1[j][6]) {
				g_num++;
			}
			else if (str1[j][0] > str1[j][1] && str1[j][1] >
				str1[j][2] && str1[j][2] > str1[j][3]
				&& str1[j][3] > str1[j][4] && str1[j][4] >
				str1[j][5] && str1[j][5] > str1[j][6] && str1[j][6] > str1[j][7]) {
				taxi++;
			}
			else {
				oth++;
			}
		}
		p[i][1] = g_num;
		p[i][2] = taxi;
		p[i][3] = oth;
	}

		int max1 =p[1][1];
		int max2 = p[1][2];
		int max3 = p[1][3];
		int dex1 = 1;
		int dex2 = 1;
		int dex3 = 1;
		for (int i = 1; i <= num; i++) {
			if (max1 > p[i][1]) {
				dex1 = i;
				max1 = p[i][1];
			}
			if (max2 > p[i][2]) {
				dex2 = i;
				max2 = p[i][2];
			}
			if (max3 > p[i][3]) {
				dex3 = i;
				max3 = p[i][3];
			}
		}
		printf("If you want to call a taxi, you should call: %s", name[dex1]);
		for (int i = 1; i <= num; i++) {
			if (p[dex1][1] == p[i][1] && dex1 != i) {
				printf(", %s",name[i]);
			}
			else break;
		}
		printf("\n");
		printf("If you want to call a taxi, you should call: %s", name[dex2]);
		for (int i = 1; i <= num; i++) {
			if (p[dex2][1] == p[i][1] && dex2 != i) {
				printf(", %s", name[i]);
			}
			else break;
		}
		printf("\n");
		printf("If you want to go to a cafe with a wonderful girl, you should call: %s", name[dex3]);
		for (int i = 1; i <= num; i++) {
			if (p[dex3][1] == p[i][1] && dex3 != i) {
				printf(", %s", name[i]);
			}
			else break;
		}
		printf("\n");
	return 0;
}

总体思路 :按照 题目要求 找出 gril taxi oth 人数 ,用数组 存起来 , 有最大值 输出最大值 如果没有 最大值 就是 输出 从第一个人 开始 向后输出 符合条件的 人

标题:codeforces (训练赛)c题题解

给定一个数n,两个人轮流写出当前数的因子,则当前的数n也就变成了该选手枚举的因子。当某一选手面临的数n为1或者质数的时候,该选手获胜。

分解质数特判 1
假设两个素数pi,pj,如果n==pi*pj(i可能等于j),则后手胜;否则先手胜。

#include<iostream>
#include<string>
#include<cstdio>

using namespace std;

long long int n;
int temp;
int p[1000];

int main() {
	while (~scanf("%lld", &n)) {
		if (n == 1) {
			cout << "1" << endl<< "0" << endl;
			continue;
		}
		temp = 0;
		for (long long int i = 2; i <= sqrt(n); i++) {
			while (n % i == 0) {
				p[temp++] = i;
				n /= i;
			}
		}
		if (n != 1) {
			p[temp++] = n;
		}
		if (temp == 1) {
			cout << "1" << endl;
			cout << "0" << endl;
		}
		else if (temp == 2) {
			cout << "2" << endl;
		}
		else {
			cout << "1" << endl;
			cout << p[0] * p[1] << endl;
		}

	}
	return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值