今天AC的题,以及测试的几道补题
题目链接:新二叉树
题解:首先这道题的数据比较小,只需定义一个结构体成员包含左右两个变量,然后定义27个即可在输入的时候因为他是小写字母,-97或者-'a'即可;是先序遍历所以遍历方式是根左右,从最开始输入的根节点开始dfs按根左右的顺序遍历即可得出结果;
AC代码:
#include <iostream>
#include <cstring>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <cstdio>
#include <stack>
#include <queue>
using namespace std;
using ll = long long;
#define up(h,n) for(int i=h;i<=n;i++)
#define down(h,n) for(int i=h;i>=n;i--)
#define wh(x) while(x--)
#define node struct node
#define ios ios::sync_with_stdio(false)
constexpr int N = 305;
constexpr int mod = 1e9 + 7;
typedef int SElemType;
node{
char left;
char right;
}tree[28];
int n;
void dfs(char x) {
if (x == '*') return;
cout << x;
dfs(tree[x - 97].left);
dfs(tree[x - 97].right);
return;
}
int main()
{
cin >> n;
char a;
cin >> a;
cin >> tree[a-97].left >> tree[a-97].right;
up(0, n - 2) {
char s;
cin >> s;
cin >> tree[s - 97].left >> tree[s - 97].right;
}
dfs(a);
return 0;
}
题目链接:https://www.luogu.com.cn/problem/P1596
题解:这里值得注意的是八个方向;先循环搜索水坑,然后水坑数+1,接着对水坑进行dfs搜索并将水坑变为旱地,防止重复搜索。
AC代码:
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <stack>
using namespace std;
using ll = long long;
#define up(h,n) for(int i=h;i<=n;i++)
#define down(h,n) for(int i=h;i>=n;i--)
#define wh(x) while(x--)
#define node struct node
#define ios ios::sync_with_stdio(false)
constexpr int N = 2000005;
constexpr int mod = 1e9 + 7;
typedef int SElemType;
int next1[8][2] = { {1,0}, {-1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, 1}, {1, -1} };//8个方向
char s[105][105];
int n, m;
void dfs(int x, int y)
{
s[x][y] = '.'; // 将水坑变为旱地,防止重复搜索
up(0, 7){// 遍历八个方向
int tx = x + next1[i][0];
int ty = y + next1[i][1];
if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if (s[tx][ty] == 'W')
dfs(tx, ty);
}
}
int main()
{
cin >> n >> m;
up(0, n - 1) {
cin >> s[i];
}
int num = 0;
up(0, n - 1) {
for (int j = 0; j < m; j++) {
if (s[i][j] == 'W') { //寻找水坑
dfs(i, j);
num++; // 水坑数加1
}
}
}
cout << num;
return 0;
}
题目链接:https://www.luogu.com.cn/problem/P2895
题解:这题要注意流星砸下来的时间要以最早的为准,还有坐标可以超过300;首先,是一道明显的bfs题,要求最短时间,所以用队列记录;陨石地图用一个二维数组记录,内容为砸下时间,以时间早为标准;再用一个二维数组记录每个点最短时间;终止条件:如果搜到一个点永远不会被陨石砸到,输出该点时间,或者直到搜索结束也没有出去,输出-1
AC代码:
#include <iostream>
#include <cstring>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <cstdio>
#include <stack>
#include <queue>
using namespace std;
using ll = long long;
#define up(h,n) for(int i=h;i<=n;i++)
#define down(h,n) for(int i=h;i>=n;i--)
#define wh(x) while(x--)
#define node struct node
#define ios ios::sync_with_stdio(false)
constexpr int N = 305;
constexpr int mod = 1e9 + 7;
typedef int SElemType;
const int next1[4][2] = { {-1,0},{1,0},{0,-1},{0,1} };
node{
int x;
int y;
int temp;//x,y坐标,temp时间
};
int m;
queue<node>q;//创建队列
int a[305][305];
int book[305][305];//标记是否走过
int x, y, t;
int main()
{
cin >> m;
up(0, 303) {
for (int j = 0; j <= 303; j++) {
a[i][j] = -9999; //陨石初始化为-9999
}
}
up(1, m) {
cin >> x >> y >> t;
if (t < a[x][y] || a[x][y] == -9999)
a[x][y] = t;
up(0, 3) { // 四个方向遍历标记陨石
int tx = x + next1[i][0];
int ty = y + next1[i][1];
if (tx >= 0 && ty >= 0 && (a[tx][ty] == -9999 || t < a[tx][ty]))
//如果该标记x,y坐标大于0且该点没有被陨石砸落或已标记时间没有该时间早,标记陨石
a[tx][ty] = t;
}
}
book[0][0] = 1; //初始点标记走过
q.push({ 0,0,0 }); //初始点入列
while (!q.empty()) { // 只要队列不空就不结束
node p = q.front(); //提取要处理的坐标
q.pop();
up(0,3) {// 进行四个方向遍历
int tx = p.x + next1[i][0];
int ty = p.y + next1[i][1];
if (tx >= 0 && ty >= 0 && book[tx][ty] == 0 && (a[tx][ty] == -9999 || p.temp + 1 < a[tx][ty])) {
// 将处理点需要x,y坐标大于等于0且该点没有走过并且陨石降落时间小于现时间
book[tx][ty] = 1;//标记已经走过
q.push({ tx,ty,p.temp + 1 }); //放入队列
if (a[tx][ty] == -9999) { //如果该点安全输出标记的时间即可
cout << p.temp + 1 << '\n';
return 0;
}
}
}
}
cout << -1 << '\n';
return 0;
}
题目链接:发送信息
题解:每次可以选择两种操作:
- 操作一:不黑屏,一直亮屏到下一次发消息(x*a)(x表示经过的时间,a表示单位时间失去的电量)
- 操作二:黑屏,到下一次发消息再亮屏(b)(b表示操作二需要花费的电量)
只需要每次发消息前比较一下哪种情况消耗的电量少,最后判断一下电量是否大于0即可
AC代码:
#include <iostream>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
long long n,f,a,b,x,m=0;
cin>>n>>f>>a>>b;
for(int i=0;i<n;i++)
{
cin>>x;
f-=min(b,(x-m)*a);
m=x;
}
if(f<=0)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
return 0;
}
题目链接:无限替换
题解:就是分情况讨论如果s2字符串中只有a,那种类也只有1,但是如果字符串中包含a,那就输出-1,剩余情况就是组合数学的内容,然后再加上s1这个种类的字符串正好为2^n,输出即可。
AC代码:
#include <bits/stdc++.h>
using namespace std ;
int main(){
int t ;
cin>> t ;
while(t--)
{
string s,t ;
cin>> s >> t ;
if(t=="a") cout<< 1 << endl ;
else if(t.find('a')!=-1) cout<< -1 << endl ;
else cout<< (long long) pow(2,s.size()) << endl ;
}
return 0;
}