第一题
int main()
{
string s;
int res = 0;
cin >> s;
for (int i = 0; i < s.size(); i++) {
res += s[i] - '0';
}
cout << res;
}
第二题
#define N 40
int mp[N][N], res[N][N];
int n, m;
void yx(int i, int j) {
int cnt = 1;
//右边
while ( j + cnt <= m && mp[i][j + cnt] == mp[i][j]) cnt++;
if (cnt >= 3)
{
for (int k = 0; k < cnt; k++)
{
res[i][j + k] = 0;
}
}
cnt = 0;
while ( i + cnt <= n && mp[i + cnt][j] == mp[i][j]) cnt++;
if (cnt >= 3)
{
for (int k = 0; k < cnt; k++)
{
res[i + k][j] = 0;
}
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
scanf("%d", &mp[i][j]);
res[i][j] = mp[i][j];
}
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
yx(i, j);
//for (int i = 1; i <= m; i++)
// for (int j = 1; j <= n - 2; j++)
// xb(mp[i][j]);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
printf("%d ", res[i][j]);
printf("\n");
}
}
第三题
memset函数有 头文件cstring, 不写会 编译错误而且没提示
memset 只能填充 -1 或 0;
#include <cstring>
memset( a, 0, sizeof(a) );
90分代码,没找到错误原因:
(2023-3-2更新,找到原因了,在遇到'+'时也要输出'+', 修改后为100分)
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
#define N 110
int n, m, q, dx[] = { -1, 0, 1, 0 }, dy[] = {0, 1, 0, -1};
char mp[N][N];
int visited[110][110];
//判断位置(a,b)是否是合法填充位置
bool validpos(int a, int b) {
if (a < 0 || a >= n || b < 0 || b >= m)
return false;
else if (mp[a][b] == '|' || mp[a][b] == '-' || mp[a][b] == '+')
return false;
else
return true;
}
//以(x,y)为中心出发的填充函数(递归)
void fill_the_blank(int x, int y, char c) {
visited[x][y] = 1;
for (int i = 0; i < 4; i++) {
int a = x + dx[i], b = y + dy[i];
if (validpos(a, b)) {
mp[a][b] = c;
if(!visited[a][b])
fill_the_blank(a, b, c);
}
}
}
int main()
{
scanf("%d%d%d", &m, &n, &q);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
mp[i][j] = '.';
}
}
for (int i = 0; i < q; i++) {
int ord;
scanf("%d", &ord);
//如果是划线指令0
if (ord == 0)
{
int x1, x2, y1, y2;
scanf("%d%d%d%d", &y1, &x1, &y2, &x2);
if (x1 == x2)
{
for (int j = min(y1, y2); j <= max(y1, y2); j++) {
if(mp[x1][j] == '|' || mp[x1][j] == '+') //最后10分更新内容
mp[x1][j] = '+';
else
mp[x1][j] = '-';
}
}
if (y1 == y2)
{
for (int j = min(x1, x2); j <= max(x1, x2); j++) {
if(mp[j][y1] == '-' || mp[j][y1] == '+')//最后10分更新内容
mp[j][y1] = '+';
else
mp[j][y1] = '|';
}
}
}
//如果是填充指令1
if(ord == 1)
{
int x, y;
char c;
scanf("%d%d %c", &y, &x, &c);
memset(visited, 0, sizeof(visited));
visited[x][y] = 1;
fill_the_blank(x, y, c);
}
}
for (int i = n - 1; i >= 0; i--)
{
for (int j = 0; j < m; j++)
{
printf("%c", mp[i][j]);
}
printf("\n");
}
}
第四题
知识点:欧拉路径
一、无向图:
是否有 欧拉路径?
如果度为奇数的点有0个或2个,则存在欧拉路径;
当度为奇数的点有2个时,欧拉路径以这两个点为起点和终点;
是否有 欧拉回路?
如果所有点的的度数都为偶数,则存在欧拉回路;
二、有向图:
是否存在 欧拉路径?
如果①“所有点入度=出度”,或者“存在一个点的入度=出度+1,一个点的入度=出度-1”,则存在欧拉路径;
是否存在 欧拉回路?
所有点的入度=出度,则存在欧拉回路;
知识点:并查集(复习一遍)
p[N]:
①定义一个数组p[N],用p[i]表示 “ i 号结点处在以 p[i] 号结点为根的集合中”;
②初始时“ p[i] = i ”
find(x):
①find(x) 返回的值是x的根节点p[x];
②如果p[x] 中暂时是当前集合的叶子结点,find(x) 会顺带将x结点连到当前集合的根节点;
合并操作:
如果x,y不在同一个集合,则将“x所在集合的 根”并入“y集合”
p[find(x)] = find(y);
注:由于这种并查集自带优化高度功能,所以效率是很高的;
const int N = 100;
int p[N];
//找到集合的根
find(int x){
//如果不是根节点,则找到其根结点并返回,这个过程中会顺便优化并查集的结构(高度)
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
//判断x,y是否在同一个集合
if(find(x) == find(y))
//如果x,y不在同一个集合,则将“x所在集合的根”并入“y集合”
if(find(x) != find(y)){
p[find(x)] = find(y);
}
知识点: 图的set存储的邻接表;
定义一个邻接表:
set<int> h[N];
加边操作:
set[a].insert(b), set[b].insert(a);
set型邻接表从k结点开始的遍历:
for(auto it = h[k].begin() ; it != h[k].end() ; it ++);
具体代码:
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
const int N = 10010, M = 100010;
set<int> h[N];
int n, m, p[N], res[M], top;
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void dfs(int a) {
//每次删一条双向路径,注意while条件一定要用size(),因为在其他递归也可能删除a的临边
while (h[a].size()) {
int b = *h[a].begin();
h[a].erase(b), h[b].erase(a);
dfs(b);
}
//回溯时记录路径,不能进入时记录(答案好像一样但是不能AC,不知道为什么)
res[++top] = a;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) p[i] = i;
for (int i = 0; i < m; i++) {
int x, y;
scanf("%d%d", &x, &y);
h[x].insert(y), h[y].insert(x);
p[find(x)] = find(y);
}
int cnt = 0;
//如果不满足欧拉路径条件则直接打印“-1”并退出
for (int i = 1; i <= n; i++) {
if (find(i) != find(1)) {
cout << -1;
return 0;
}
if (h[i].size() % 2)
cnt++;
}
if (cnt != 0 && cnt != 2 || cnt == 2 && h[1].size() % 2 == 0) {
cout << -1;
return 0;
}
//满足欧拉条件则从1出发必有欧拉路径,进行dfs
dfs(1);
for (int i = top; i; i--) {
printf("%d ", res[i]);
}
return 0;
}