一.STL
1.
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n, k, sum=0;
cin >> n >> k;
vector<int>a(n),b(n),c(n);
for(int i=0; i<n; i++) cin>>a[i];
for(int i=0; i<n; i++){
cin >> b[i];
c[i] = a[i]-b[i];
sum += b[i];
}
sort(c.begin(),c.end(),greater<int>());
for(int i=0;i<k;i++) sum += c[i];
cout<<sum;
return 0;
}
2.
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
//不足三个元素
if(n<3){
cout<<"No solution";
return 0;
}
vector<int> a(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
//对三角元素进行排序
sort(a.begin(),a.end());
for(int i=2;i<n;i++){
if(a[i-2]+a[i-1]>a[i]){
cout<<a[i-2]<<" "<<a[i-1]<<" "<<a[i];
return 0;
}
}
cout<<"No solution";
return 0;
}
3.
#include <bits/stdc++.h>
using namespace std;
bool cmp(string x, string y)
{
return x+y>y+x;
}
int main()
{
int n;
cin >> n;
vector<string> a(n);
for(int i=0; i<n; i++)
{
cin >> a[i];
}
sort(a.begin(),a.end(),cmp);
for(int i=0; i<n; i++)cout<<a[i];
return 0;
}
4.
#include <bits/stdc++.h>
using namespace std;
int a;
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
string s;
cin >> s;
int len = s.size();
for(int i=0; i<s.size(); i++)
{
if(s[i] == 'a')a ++;
else a--;
if(a<0 || (a!=0 && i==s.length()-1)){
cout<<"Bad";
return 0;
}
}
if(s[len-1] == 'a')
cout << "Bad";
else cout << "Good";
return 0;
}
5.
#include<stack>
#include<iostream>
using namespace std;
const int N=1e7+9;
int a[N],b[N];
stack<int> q;
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i=n-1; i>=0; i--) b[i] = max(a[i],b[i+1]);
for(int i=0; i<n; i++){
q.push(a[i]);
while(!q.empty() && q.top()>b[i+1])
{
cout<<q.top()<<" ";
q.pop();
}
}
}
6.
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main() {
string str;
// 修改处:添加循环以处理多组输入
while (cin >> str) {
stack<char> st;
for (char ch : str) {
if (!st.empty()) {
// 检查栈顶和当前字符的关系
if (st.top() == 'o' && ch == 'o') {
st.pop(); // 弹出 'o'
// 检查栈是否为空后再操作
if (!st.empty() && st.top() == 'O') {
st.pop(); // 弹出 'O'
} else {
st.push('O'); // 压入 'O'
}
}
else if (st.top() == 'O' && ch == 'O') {
st.pop(); // 弹出 'O'
}
else {
st.push(ch); // 直接压入
}
}
else {
st.push(ch); // 栈为空,直接压入
}
}
// 将栈中的字符拼接成结果字符串
string result;
while (!st.empty()) {
result = st.top() + result; // 正确拼接顺序
st.pop();
}
cout << result << endl;
}
return 0;
}
7.
class Solution {
public:
long long temp1;
long long temp2;
long long num=0;
long long legalExp(string str) {
stack<long long>s;
for(auto &s1:str)
{
if(s1=='#')
{
s.push(num);
num=0;
}
else if(s1>='0'&&s1<='9')
{
num=num*10+s1-'0';
}
else if(s1=='+')
{
temp1=s.top();
s.pop();
temp2=s.top();
s.pop();
s.push(temp1+temp2);
}
else if(s1=='-')
{
temp1=s.top();
s.pop();
temp2=s.top();
s.pop();
s.push(temp2-temp1);
}
else if(s1=='*')
{
temp1=s.top();
s.pop();
temp2=s.top();
s.pop();
s.push(temp1*temp2);
}
}
return s.top();
}
};
8.
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int m, k;
int main()
{
set<int> s;
scanf("%d%d",&m,&k);
while (m--)
{
char op[6];
int x;
scanf("%s%d",op,&x);
if(*op == 'a') //整个区间没有这个[x-k,x+k] 就插入
{
if(s.lower_bound(x - k) == s.upper_bound(x + k)) s.insert(x);
}
else if(*op == 'd') //注意s.erase 函数的用法 这里是妙用
{
if(s.size()) s.erase(s.lower_bound(x - k), s.upper_bound(x + k));
}
else
{
if(s.lower_bound(x - k) == s.upper_bound(x + k)) puts("No");
else puts("Yes");
}
}
return 0;
}
9.洛谷p1440
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<deque>
using namespace std;
const int maxsize = 2000010;
int n,m;
struct node
{
int val;
int pos;
}A[maxsize];
deque<node> min_Q;
inline int rd()
{
int data = 0;
int f = 1;
char ch = getchar();
while(ch < '0'||ch > '9')
{
if(ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0'&&ch <= '9')
{
data = (data<<3) + (data<<1) + ch - '0';
ch = getchar();
}
return f * data;
}
int min_que[maxsize];
int main()
{
n = rd(),m = rd();
for(int i = 1;i <= n;i++)
{
A[i].val = rd();
A[i].pos = i - 1;
}
min_que[0] = 0;
for(int i = 1;i < n;i++)
{
while(!min_Q.empty()&&min_Q.back().val >= A[i].val)
min_Q.pop_back();
min_Q.push_back(A[i]);
while(!min_Q.empty()&&min_Q.front().pos < i - m)
min_Q.pop_front();
min_que[i] = min_Q.front().val;
}
for(int i = 0;i < n;i++)
printf("%d\n",min_que[i]);
return 0;
}
二.搜索
1.走出迷宫(dfs
#include <bits/stdc++.h>
using namespace std;
int aa[4] = {-1,1,0,0}, bb[4] = {0,0,1,-1};
char a[600][600];
int n, m, flag=0;
int vis[600][600];
void dfs(int xb, int yb)
{
if(xb > n || xb < 1 || yb <1 || yb>m || vis[xb][yb] == 1 || a[xb][yb]=='#') return;
if(a[xb][yb] == 'E')
{
flag = 1;
return;
}
vis[xb][yb] = 1;
for(int i=0; i<4; i++)
{
dfs(xb+aa[i], yb+bb[i]);
}
return;
}
int main()
{
while(cin >> n >> m)
{
int xb, yb;
flag = 0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin >> a[i][j];
vis[i][j] = 0;
if(a[i][j] == 'S')
{
xb = i;
yb = j;
}
}
}
dfs(xb,yb);
if(flag) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
2.迷宫(bfs
#include<bits/stdc++.h>
using namespace std;
const int N=505;
char s[N][N];
int vis1[N][N];//拿到钥匙前是否走过
int vis2[N][N];//拿到钥匙后是否走过
int key;
int h,w;
struct node{
int x,y,step,key;//key记录有没有拿到钥匙
};
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
queue<node>q;
int bfs(int sx,int sy){
q.push(node{sx,sy,0,0});
vis1[sx][sy]=1;
while(!q.empty()){
int x=q.front().x;
int y=q.front().y;
int step=q.front().step;
int key=q.front().key;
q.pop();
if(s[x][y]=='E') return step;
for(int i=0;i<4;i++){
int xx=x+dx[i];
int yy=y+dy[i];
if(!(xx>=0&&xx<h&&yy>=0&&yy<w&&s[xx][yy]!='W')) continue;
if(key){
if(vis2[xx][yy]==1) continue;
vis2[xx][yy]=1;
q.push(node{xx,yy,step+1,1});
}else {
if(s[xx][yy]=='D'||vis1[xx][yy]==1) continue;
vis1[xx][yy]=1;
if(s[xx][yy]=='K') q.push(node{xx,yy,step+1,1});//拿到钥匙了
else q.push(node{xx,yy,step+1,0});
}
}
}
return -1;
}
int main(){
cin>>h>>w;
int sx, sy;
for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
cin>>s[i][j];
if(s[i][j]=='S'){
sx=i,sy=j;
vis1[i][j]=0,vis2[i][j]=0;
}
}
}
key=0;
cout<<bfs(sx,sy)<<endl;
return 0;
}
3.jelly(bfs
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
char mp[N][N][N];
int vis[N][N][N];
int dx[6]={0,0,-1,1,0,0};
int dy[6]={0,0,0,0,1,-1};
int dz[6]={1,-1,0,0,0,0};
struct node{
int x, y, z;
};
int n;
int res = 0;
void bfs()
{
queue<node> q;
q.push({1, 1, 1});
vis[1][1][1] = 1;
while(!q.empty())
{
auto t = q.front();
q.pop();
for(int k=0 ;k < 6;k++)
{
int x=t.x+dx[k],y=t.y+dy[k],z=t.z+dz[k];
if(x>0&&x<=n&&y>0&&y<=n&&z>0&&z<=n&&mp[x][y][z]!='*'&&!vis[x][y][z]){
vis[x][y][z]= vis[t.x][t.y][t.z]+1;
q.push({x,y,z});
}
}
}
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
for(int k = 1; k <= n; k++)
cin >> mp[i][j][k];
bfs();
if(vis[n][n][n] == 0)
cout << "-1";
else
cout << vis[n][n][n];
}
4.1~n个数的集合 选择/不选择
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
int n, st[100];
void dfs(int x)
{
if(x > n)
{
for(int i=1; i<=n; i++)
{
if(st[i] == 1){
cout << i;
}
}
cout << endl;
return;
}
//选
st[x] = 1;
dfs(x+1);
st[x] = 0;
//不选
st[x] = 2;
dfs(x+1);
st[x] = 0;
}
int main()
{
IOS;
n = 3;
dfs(1);
return 0;
}
/*
输出:
123
12
13
1
23
2
3
*/
5.排列型枚举
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int n;
bool st[N];
int arr[N];
void dfs(int x)
{
if(x > n)
{
for(int i=1; i<=n; i++)
{
cout << arr[i];
}cout << endl;
return ;
}
for(int i=1; i<=n; i++)
{
if(!st[i]){
st[i] = true;
arr[x] = i;
dfs(x+1);
st[i] = false;
//arr[i] = 0;
}
}
}
int main()
{
cin >> n;
dfs(1);
return 0;
}
/*
输入3:
输出:
123
132
213
231
312
321
*/
6.选择排列
#include <bits/stdc++.h>
using namespace std;
const int N=10;
int n, r;
int arr[N];
void dfs(int x, int start)
{
if(x > r)
{
for(int i=1; i<=r; i++)
{
cout << arr[i];
}
cout << endl;
return;
}
for(int i=start; i<=n; i++)
{
arr[x] = i;
dfs(x+1, i+1);
arr[x] = 0;
}
}
int main()
{
n=5, r=3;
dfs(1,1);
return 0;
}
/*输出:
123
124
125
134
135
145
234
235
245
345
*/
7.洛谷P1065
#include <bits/stdc++.h>
#define up(l,r,i) for(int i=l;i<=r;i++)
#define dn(l,r,i) for(int i=r; i>=l;i--)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
int n, m, t, ans;
int sx,sy,fx,fy;
int a[10][10];
int aa[]={1,-1,0,0}, bb[]={0,0,1,-1};
bool vis[10][10];
void dfs(int x, int y)
{
if(x<1 || x>n || y<1 || y>n) return;
if(vis[x][y]) return;
//vis[x][y] = true;
if(a[x][y] == 1) return;
if(x == fx && y == fy)
{
ans++;
return;
}
up(0,3,i)
{
vis[x][y] = true;
dfs(x+aa[i],y+bb[i]);
vis[x][y] = false;
}
}
int main()
{
IOS;
cin >> n >> m >> t;
cin >> sx >> sy >> fx >> fy;
while(t--)
{
int xx, yy;
cin >> xx >> yy;
a[xx][yy] = 1;
}
dfs(sx,sy);
cout << ans;
return 0;
}
8.洛谷P1101
#include<iostream>
using namespace std;
int n,u[8]={0,-1,-1,-1,0,1,1,1},v[8]={1,1,0,-1,-1,-1,0,1};//八个方向
char le[200],chess[101][101];
bool ma[101][101];
bool DFS(int x,int y,char w,int p){//我在哪,我是什么字母,我现在的方向是哪
if(w=='g'){//最后一个字母判断成功,标记,返回
ma[x][y]=1;
return 1;
}
int xx=x+u[p],yy=y+v[p];
if(xx>=1 && yy>=1 && xx<=n && yy<=n && chess[xx][yy]==le[w])//搜索,不解释
if(DFS(xx,yy,le[w],p)){
ma[x][y]=1;
return 1;
}
return 0;
}
int main(){
le['y']='i';
le['i']='z';
le['z']='h';
le['h']='o';
le['o']='n';
le['n']='g';//把单词串在一起
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>chess[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(chess[i][j]=='y')//如果是单词开头
for(int k=0;k<=7;k++)//就八个方向搜索
if(DFS(i,j,'y',k)) ma[i][j]=1; //判断是否成单词
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
if(ma[i][j]) cout<<chess[i][j];
else cout<<'*';
cout<<endl;
}
return 0;
}
9.洛谷P1162
#include <bits/stdc++.h>
using namespace std;
int a[32][32],b[32][32];
int dx[5]={0,-1,1,0,0};
int dy[5]={0,0,0,-1,1};//第一个表示不动,是充数的,后面的四个分别是上下左右四个方向
int n,i,j;
void dfs(int p,int q){
int i;
if (p<0||p>n+1||q<0||q>n+1||a[p][q]!=0) return;//如果搜过头或者已经被搜过了或者本来就是墙的就往回
a[p][q]=1;//染色
for (i=1;i<=4;i++) dfs(p+dx[i],q+dy[i]);//向四个方向搜索
}
int main(){
cin>>n;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++){
cin>>b[i][j];//其实不拿两个数组也可以,不过我喜欢啦
if (b[i][j]==0) a[i][j]=0;
else a[i][j]=2;
}
dfs(0,0);//搜索 从0,0开始搜
for (i=1;i<=n;i++){
for (j=1;j<=n;j++)
if (a[i][j]==0) cout<<2<<' ';//如果染过色以后i,j那个地方还是0,说明没有搜到,就是周围有墙,当然就是被围住了,然后输出2
else cout<<b[i][j]<<' ';//因为被染色了,本来没有被围住的水和墙都染成了1,所以就输出b[i][j]
cout<<'\n';//换行
}
10.洛谷P2404
#include<iostream>
using namespace std;
int n, a[10001], temp;//利用temp来计入数组的值
void print() {
int count = 1;
while (a[count]) {
if (!a[count + 1]) cout << a[count];//最后一次输出
else cout << a[count] << "+";//其它输出
count++;
}
cout << endl;
return ;
}
void dfs(int x) {
int i;
if (temp == n) {//当temp的值达到要拆分的自然数的值的时候
print();
return ;
}
for (i = 1; i < n; i++) {
if (i >= a[x - 1]) {//算式后面的数要比前面的数大或相等
a[x] = i;
temp += a[x];
if (temp > n) {
temp -= a[x];//防止temp数过大
a[x] = 0;
break;
}
dfs(x + 1);
temp -= a[x];
a[x] = 0;
//回溯
}
}
}
int main() {
cin >> n;
dfs(1);
return 0;
}
11.p2392
#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
int s[5];
int a[21][5];
int minn, Left, Right, ans;
void search(int x, int y) {
if(x > s[y]) {
minn = min(minn, max(Left,Right));
return;
}
Left += a[x][y];
search(x+1,y);
Left -= a[x][y];
Right += a[x][y];
search(x+1,y);
Right -= a[x][y];
}
signed main()
{
cin >> s[1] >> s[2] >> s[3] >> s[4];
for (int i=1; i<=4; i++) {
Left = Right = 0;
minn = 19260817;
for (int j=1; j<=s[i]; j++) {
cin >> a[j][i];
}
search(1,i);
ans += minn;
}
cout << ans;
return 0;
}
12.p1596
#include <bits/stdc++.h>
using namespace std;
int fxx[9]={0,-1,-1,-1,0,0,1,1,1};
int fxy[9]={0,-1,0,1,-1,1,-1,0,1};
int n, m, ans;
char a[105][105];
void dfs(int x, int y)
{
int r, c;
a[x][y] = '.';
for (int i=1; i<=8; ++i) {
r = x+fxx[i];
c = y+fxy[i];
if(r<1||r>n||c<1||c>m||a[r][c] == '.')
continue;
a[r][c] = '.';
dfs(r,c);
}
}
int main()
{
cin >> n >> m;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
cin >> a[i][j];
}
}
ans = 0;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
if(a[i][j] == 'W') {
ans ++;
dfs(i,j);
}
}
}
cout << ans;
return 0;
}
13.2895
#include <bits/stdc++.h>
// 宏定义将int类型重定义为long long,避免在计算过程中出现整数溢出
#define int long long
// 宏定义优化输入输出流,提高程序运行效率
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
// n 表示流星的数量
// ma 二维数组用于记录每个坐标最早被流星摧毁的时间,初始化为 -1 表示未被摧毁
// v 二维数组用于标记某个坐标是否已经被访问过
// sx, sy 分别表示流星撞击的 x, y 坐标,st 表示流星撞击的时间
// ans 二维数组用于记录到达每个坐标所需的最短时间
int n, ma[305][305], v[305][305], sx, sy, st, ans[305][305];
// dx 和 dy 数组用于表示上下左右四个方向的偏移量,用于后续坐标的移动
int dx[5] = {0, 0, 0, 1, -1};
int dy[5] = {0, 1, -1, 0, 0};
// 辅助函数,将 -1 转换为一个很大的数 99999
// 用于在比较时,将未被摧毁的坐标的时间视为一个很大的值
int ch(int a) {
if (a == -1) return 99999;
else return a;
}
signed main() {
// 调用优化输入输出的宏
IOS;
// 输入流星的数量
cin >> n;
// 初始化 ma 数组,将所有坐标的最早摧毁时间初始化为 -1
for (int i = 0; i < 305; i++) {
for (int j = 0; j < 305; j++) {
ma[i][j] = -1;
}
}
// 读取每颗流星的信息
for (int i = 1; i <= n; i++) {
// 输入流星撞击的 x, y 坐标和时间
cin >> sx >> sy >> st;
// 遍历当前流星撞击点及其上下左右四个相邻点
for (int j = 0; j < 5; ++j) {
// 检查新坐标是否合法(x 和 y 坐标都非负)
// 并且新坐标未被记录过或者新记录的时间更早
if (sx + dx[j] >= 0 && sy + dy[j] >= 0 && (ma[sx + dx[j]][sy + dy[j]] == -1 || ma[sx + dx[j]][sy + dy[j]] > st))
// 更新该坐标最早被摧毁的时间
ma[sx + dx[j]][sy + dy[j]] = st;
}
}
// 定义两个队列,分别存储 x 和 y 坐标,用于广度优先搜索
queue<int> q[2];
// 标记起点 (0, 0) 已经被访问
v[0][0] = 1;
// 将起点 (0, 0) 加入队列
q[0].push(0);
q[1].push(0);
// 开始广度优先搜索
while (!q[0].empty()) {
// 取出队列头部的坐标
int x = q[0].front(), y = q[1].front();
// 弹出队列头部元素
q[0].pop();
q[1].pop();
// 计算到达下一个位置所需的时间
int s = ans[x][y] + 1;
// 如果当前坐标永远不会被摧毁(最早摧毁时间为 -1)
if (ma[x][y] == -1) {
// 输出到达该坐标所需的时间
cout << s - 1;
// 结束程序
return 0;
}
// 尝试向上下左右四个方向移动
for (int i = 1; i <= 4; i++) {
// 计算新的坐标
int xx = x + dx[i], yy = y + dy[i];
// 检查新坐标是否合法(x 和 y 坐标都非负)
// 并且到达新坐标的时间早于该坐标最早被摧毁的时间
// 同时新坐标未被访问过
if (xx >= 0 && yy >= 0 && s < ch(ma[xx][yy]) && v[xx][yy] == 0) {
// 将新坐标加入队列
q[0].push(xx);
q[1].push(yy);
// 标记新坐标已被访问
v[xx][yy] = 1;
// 记录到达新坐标所需的时间
ans[xx][yy] = s;
}
}
}
// 如果队列为空还未找到安全的位置,输出 -1 表示无法到达安全位置
cout << -1 << endl;
return 0;
}
14.p1467
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
long long m; // 存储输入的数字,后续用于寻找比它大的循环数
int num[20], cnt = 1, a[20]; // num用于临时保存数字分解后的各位;cnt记录数字的位数;a辅助处理数字分解
int b[15] = {0}; // 用于统计数字出现次数,判断是否有重复数字或包含0
// 功能:将输入数字x分解为各位数字,并做预处理
void get(long long x) {
for (int i = 0; i <= 9; i++) { // 重置b数组,清空之前的统计结果
b[i] = 0;
}
cnt = 1;
while (x != 0) {
a[cnt] = x % 10; // 取x的最后一位数字
x /= 10; // 去掉x的最后一位数字
cnt++;
}
cnt--; // 修正cnt为数字的实际位数
memcpy(num, a, sizeof(num)); // 将a数组内容复制到num数组
for (int i = 1; i <= cnt; i++) { // 调整a数组,使数字按正常顺序存储(原a数组是逆序存储)
a[cnt - i + 1] = num[i];
}
}
// 功能:判断数字x是否为循环数
bool keyi(long long x) {
get(x); // 先分解数字x并预处理
for (int i = 1; i <= cnt; i++) {
if (a[i] == 0) return false; // 包含0,不是循环数
b[a[i]]++; // 统计每个数字出现次数
}
for (int i = 0; i <= 9; i++) { // 检查数字是否重复
if (b[i] > 1) return false; // 有重复数字,不是循环数
b[i] = 0; // 重置b数组,为后续判断准备
}
int i = 1, h = 1;
while (i <= cnt) { // 模拟循环数的移动判断逻辑
int o = h;
h = h + a[h]; // 从当前位置h移动a[h]步
while (h > cnt) { h -= cnt; } // 处理越界,循环回到开头
if (a[o] == a[h]) { // 停在相同数字,不是循环数
return false;
}
b[h]++; // 标记该位置已访问
i++;
}
int ans = 0;
for (int i = 0; i <= 9; i++) { // 检查是否每个位置都访问过一次
if (b[i] == 1) ans++;
}
if (ans != cnt) { // 访问位置数与位数不等,不是循环数
return false;
} else {
return true; // 满足循环数条件
}
}
int main() {
cin >> m;
m++; // 找比m大的循环数,先自增1
while (!keyi(m)) { // 循环判断,直到找到循环数
m++;
}
cout << m; // 输出找到的第一个符合条件的循环数
return 0;
}
15.p1451
#include<bits/stdc++.h>
using namespace std;
// 定义坐标结构体,用于队列中存储点的坐标
struct zuobiao{
int x,y;
}q[30000];
// 用二维数组 graph 存储图,p 数组用于标记点是否已被访问
bool graph[200][200], p[200][200];
int n,m,ans;
char a;
// 数组储存四个方向:右、下、上、左
int c[4][2] = {0,1,1,0,-1,0,0,-1};
// 广度优先搜索函数,用于搜索一个细胞区域
void bfs(int x,int y)
{
ans++; // 发现一个新的细胞,细胞数量加 1
int f = 0, r = 1, X, Y; // f 为队首,r 为队尾
q[1].x = x;
q[1].y = y;
while(f < r)
{
f++; // 队首指针后移
X = q[f].x;
Y = q[f].y;
p[X][Y] = 1; // 标记该点已被访问
for(int i = 0; i < 4; i++) // 循环遍历四个方向
{
int xx = X + c[i][0];
int yy = Y + c[i][1];
// 如果该点是数字且未被访问过
if(graph[xx][yy] && (!p[xx][yy]))
{
q[++r].x = xx; // 将该点加入队列尾部
q[r].y = yy;
}
}
}
}
int main()
{
cin >> m >> n;
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
cin >> a;
if(a >= '1' && a <= '9')
{
graph[i][j] = true; // 如果输入字符是 1 - 9,标记该点为有数字
}
else
{
graph[i][j] = false; // 否则标记为无数字
}
}
}
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if(!p[i][j] && graph[i][j])
{
bfs(i,j); // 如果该点未被访问且是数字,进行广度优先搜索
}
}
}
cout << ans; // 输出细胞的数量
return 0;
}
16.p1454
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const int dx[13]={0,1,-1,0,0,2,-2,0,0,1,-1,1,-1};
const int dy[13]={0,0,0,1,-1,0,0,2,-1,-1,1,1,-1};
char a[1001][1001];
int n, m, ans;
void dfs(int x, int y)
{
int i;
if(x<1 || x>n || y<1 || y> m || a[x][y]!='#') return;
a[x][y] = '-';
for (int i=1; i<=12; ++i) dfs(x+dx[i], y+dy[i]);
}
int main()
{
IOS;
int i, j;
cin >> n >> m;
for (int i=1; i<=n; i++)
for(int j=1; j<=m; ++j)
cin >> a[i][j];
for (int i=1; i<=n; ++i)
{
for (int j=1; j<=m; ++j)
{
if(a[i][j] == '#')
{
ans++;
dfs(i,j);
}
}
}
cout << ans;
return 0;
}
17.p1479
#include<bits/stdc++.h>
using namespace std;
int n;
bool q[15];
bool a[6][6]={false};
int ans = 0;
void c()
{
int cnt = 0;
for(int i=1; i<=5; ++i)
{
if(a[i][1]&&a[i][2]&&a[i][3]&&a[i][4]&&a[i][5]) cnt++;
if(a[1][i]&&a[2][i]&&a[3][i]&&a[4][i]&&a[5][i]) cnt++;
}
if(a[1][1]&&a[2][2]&&a[3][3]&&a[4][4]&&a[5][5]) cnt++;
if(a[1][5]&&a[2][4]&&a[3][3]&&a[4][2]&&a[5][1]) cnt++;
q[cnt] = true;
}
void dfs(int x, int y, int sum)
{
if(x==6 || sum==n+1)
{
if(sum==n+1) c();
return;
}
if(y==6) dfs(x+1,1,sum);
else{
a[x][y] = true;
dfs(x,y+1,sum+1);
a[x][y] = false;
dfs(x,y+1,sum);
a[x][y] = false;
}
}
int main()
{
cin >> n;
dfs(1,1,1);
for(int i=1; i<=15; ++i)
{
if(q[i]) ans += i;
}
cout << ans;
return 0;
}
18.p1926
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
int ans, n, k;
// dfs 函数用于递归搜索分苹果的不同方法
// pos: 当前处理的盘子序号(从 0 开始计数)
// now: 当前盘子放置苹果数的下限(保证分法不重复,按非递减顺序放置)
// lftv: 剩余未分配的苹果数量
void dfs(int pos, int now, int lftv) {
// 当处理完 k 个盘子且苹果刚好分完时,找到一种合法分法
if (pos == k && !lftv) {
ans++; // 分法数量加 1
return;
}
// 若盘子已处理完或苹果不够分,结束当前分支
if (pos == k || lftv < 0) return;
// 枚举当前盘子放置的苹果数,从 now 开始保证分法不重复(非递减)
for (int i = now; i <= lftv; i++) {
dfs(pos + 1, i, lftv - i); // 递归处理下一个盘子,更新剩余苹果数
}
}
int main() {
int t;
IOS; // 优化输入输出性能,关闭同步并绑定缓冲区
cin >> t;
while (t--) {
ans = 0;
cin >> n >> k;
dfs(0, 0, n); // 从第 0 个盘子开始,当前盘子放 0 个苹果,剩余 n 个苹果待分配
cout << ans << endl; // 输出当前测试用例的分法数量
}
return 0;
}
19.p2372
//bfs
#include<stdio.h>
#include<iostream>
using std::cin; // 使用cin读入,自动忽略换行和空格
#include<queue>
using std::queue; // 使用队列
bool f[21][21]; // 标记数组,用于记录网格中的点是否被访问过
char map[21][21]; // 存储网格地图
int n, m, x, y, ans;
// 8个方向的偏移量,用于遍历周围的点
int fx[8] = {0, 0, -1, 1, -1, -1, 1, 1},
fy[8] = {-1, 1, 0, 0, -1, 1, -1, 1};
queue<int> Qx, Qy; // 两个队列,分别存储点的横坐标和纵坐标
void BFS(void); // 广度优先搜索函数声明
int main(void) {
register int i, j, k, dx, dy; // 使用寄存器变量,提高访问速度
scanf("%d%d%d%d", &m, &n, &x, &y); // 输入网格大小和踩中的坐标
Qx.push(x), Qy.push(y); // 将踩中的坐标入队
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
cin >> map[i][j]; // 读入网格地图
BFS(); // 进行广度优先搜索,标记目标区域
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
if (f[i][j]) // 如果该点属于目标区域
for (k = 0; k < 4; k++) { // 遍历上下左右四个方向(只计算上下左右边界,因为周长计算只看这四个方向)
dx = i + fx[k], dy = j + fy[k];
if (!f[dx][dy]) // 如果相邻点不属于目标区域,说明是周长的一部分
ans++;
}
printf("%d", ans); // 输出目标的周长
return 0; // 程序正常结束
}
void BFS(void) {
register int i, x, y, dx, dy; // 使用寄存器变量,提高访问速度
while (!Qx.empty()) { // 队列不为空时循环
x = Qx.front(), y = Qy.front(); // 取出队首的坐标
Qx.pop(), Qy.pop(); // 队首元素出队
f[x][y] = true; // 标记该点已访问
for (i = 0; i < 8; i++) { // 遍历8个方向
dx = x + fx[i], dy = y + fy[i];
// 越界处理,忽略越界的点
if (dx < 1 || m < dx || dy < 1 || n < dy)
continue;
// 如果是'X'且未被访问过,将其入队
else if (map[dx][dy] == 'X' && !f[dx][dy])
Qx.push(dx), Qy.push(dy);
}
}
return;
}
//dfs
#include<bits/stdc++.h>
using namespace std;
int m,n,x,y,ans,pd[22][22],dx[8]={-1,-1,1,1,-1,0,0,1},dy[8]={-1,1,-1,1,0,-1,1,0};
//pd:判断这个方格有没有被访问过,dx和dy:搜索时的方向(0-3是四个角,4-7是上下左右)
char k[22][22];
void dfs(int a,int b)
{
pd[a][b]=1;//标记这个方格已经被访问过
for(int c=0;c<8;c++){
int d=dx[c]+a, e=dy[c]+b;
if(d>0&&d<=m&&e>0&&pd[d][e]==0&&k[d][e]=='X')dfs(d,e);//如果这个格子没出界,没被访问过并且显示的是'X',就访问这个格子
if(c>3&&(d<=0||d>m||e<=0||e>n||k[d][e]!='X'))ans++;//如果方向是上下左右,并且出界了或者显示的不是'X',周长就要+1
}
}
int main()
{
cin>>m>>n>>x>>y;
for(int a=1;a<=m;a++)
for(int b=1;b<=n;b++)
cin>>k[a][b];
dfs(x,y),cout<<ans;
return 0;
}
20.
#include <bits/stdc++.h>
using namespace std;
// f[105][105]:二维布尔数组,用于存储图的邻接关系,f[i][j]为true表示顶点i和顶点j有边相连
// 这里数组大小设为105是为容纳可能的顶点编号(预留一定空间)
bool f[105][105];
// color[105]:一维整型数组,记录每个顶点所着的颜色,color[i]表示顶点i的颜色编号(1到m)
int color[105];
// num:用于统计不同着色方案的数量,初始为0,找到合法方案时自增1
int num = 0;
// n:图的顶点个数,k:边的条数,m:颜色的种数,通过输入获取具体值
int n, k, m;
// check函数:检查当前顶点sum所着颜色是否与相邻顶点颜色相同
// 参数sum:当前正在检查的顶点编号
// 若存在相邻顶点颜色相同,返回false,否则返回true
bool check(int sum) {
for (int i = 1; i <= sum; ++i) {
// 如果i和sum有边相连且颜色相同,返回false
if (f[i][sum] == true && color[i] == color[sum]) {
return false;
}
}
return true;
}
// dfs函数:采用深度优先搜索算法,尝试对图的每个顶点进行着色
// 参数s:当前正在处理的顶点编号
void dfs(int s) {
// 如果当前顶点编号s大于顶点总数n,说明所有顶点已成功着色,找到一种合法方案,num自增并返回
if (s > n) {
num++;
return;
}
// 遍历1到m这m种颜色,尝试给当前顶点s着上颜色i
for (int i = 1; i <= m; ++i) {
color[s] = i;
// 检查这种着色是否合法,若合法则递归对下一个顶点进行着色
if (check(s)) {
dfs(s + 1);
}
// 若不合法,将color[s]重置为0,继续尝试下一种颜色
else {
color[s] = 0;
}
}
}
int main() {
// 读取图的顶点个数n、边的条数k和颜色种数m
cin >> n >> k >> m;
// 读取每条边的两个顶点x和y,并记录图的邻接关系
for (int i = 1; i <= k; ++i) {
int x, y;
cin >> x >> y;
f[x][y] = true;
f[y][x] = true;
}
// 将color数组初始化为0,表示所有顶点还未着色
memset(color, 0, sizeof(color));
// 从顶点1开始进行深度优先搜索,尝试对整个图进行着色
dfs(1);
// 输出统计得到的不同着色方案数num
cout << num;
return 0;
}
21.p8662
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1005;
char a[N][N];
int n, ans;
int xx[] = {1, -1, 0, 0}, yy[] = {0, 0, 1, -1};
bool v = 1;
bool vis[N][N];
// 判断坐标(x, y)处是否为陆地,是则返回true,否则返回false
bool ok(int x, int y) {
return a[x][y] != '.';
}
// 深度优先搜索函数,从(x, y)开始遍历岛屿,判断岛屿是否会被完全淹没
bool dfs(int x, int y) {
vis[x][y] = 1;
// 若上下左右相邻像素都是陆地,说明岛屿不会被完全淹没,v设为0
if (ok(x - 1, y) && ok(x + 1, y) && ok(x, y + 1) && ok(x, y - 1)) {
v = 0;
}
for (int i = 0; i < 4; ++i) {
int X = x + xx[i], Y = y + yy[i];
// 若相邻像素是陆地且未被访问过,递归进行深度优先搜索
if (ok(X, Y) && vis[X][Y] == 0) {
dfs(X, Y);
}
}
a[x][y] = '.'; // 搜索完将当前像素标记为海洋
return v;
}
int main() {
cin >> n;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
cin >> a[i][j];
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (ok(i, j)) {
v = 1;
ans += dfs(i, j);
}
}
}
cout << ans;
return 0;
}
22.
#include<bits/stdc++.h>
using namespace std;
int n;
int vis[1005][1005];
int h[4]={0,0,1,-1},s[4]={1,-1,0,0};
//h、s数组代表可以走的上下左右四个方向
char a[1005][1005];
//a数组表示地图
struct node{
int x,y;
};
//结构体
queue<node>q;
//如上,队列q
bool check(int x,int y){
if(a[x][y]=='1')
return false;
//如果是障碍物,就返回false
if(vis[x][y]>0)
return false;
//如果以前走过了,就返回false
if(x>n||x<1)
return false;
if(y>n||y<1)
return false;
//如果超出地图边界,就返回false
return true;
//如果它通过了重重考验,就给它过吧
}
void bfs(int x,int y){
vis[x][y]=1;
//标记起点
q.push((node){x,y});
//把起点和终点放进队列q里
while(q.size()!=0){
//如果队列里还有数,就继续
int xx=q.front().x;
int yy=q.front().y;
//把队列里的数取出来
q.pop();
//用过了就把它扔了
for(int i=0;i<4;i++){
//代表四个方向
int xxx=xx+h[i];
int yyy=yy+s[i];
//向某一个方向前进
if(check(xxx,yyy)){
vis[xxx][yyy]=vis[xx][yy]+1;
//记录步数
q.push((node){xxx,yyy});
//把通过的答案扔进队列里
}
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
//地图
int x1,x2,y1,y2;
//x1表示起点的横坐标,x2表示起点的纵坐标
scanf("%d%d%d%d",&x1,&x2,&y1,&y2);
bfs(x1,x2);
printf("%d",vis[y1][y2]-1);
//输出答案减一,它把起点也算了一步
return 0;
}
23.
#include <iostream>
#include <string>
using namespace std;
string a;
int n;
char b(int c, int d) {
if(c == d) {
if(a[c] == '0'){
cout << 'B';
return 'B';
} else {
cout << 'I';
return 'I';
}
}
int e = (c + d) / 2;
char f = b(c, e);//左子树类型
char g = b(e+1, d);//右子树类型
char h;
if(f == 'B' && g == 'B') {
h = 'B';
}else if(f == 'I' && g == 'I') {
h = 'I';
}else h = 'F';
cout << h;
return h;
}
int main()
{
cin >> n >> a;
int j = a.length();
dfs(0, j-1);
return 0;
}
24.走楼梯(记忆化
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
const int N = 20;
int n;
int mem[N];
int dfs(int x) {
if(mem[x]) return mem[x];
itn sum = 0;
if(x == 1) sum = 1;
else if(x == 2) sum = 2;
else sum = dfs(x-1) + dfs(x-2);
mem[x] = sum;
return sum;
}
signed main()
{
IOS;
scanf("%d", &n);
int res = dfs(n);
printf("%d\n", res);
return 0;
}
三、优先队列
1.合并果子
#include<bits/stdc++.h>
using namespace std;
// 定义一个最小堆优先队列
priority_queue<int, vector<int>, greater<int>> q;
int n, sum, x, a, b;
int main() {
// 读取元素的数量
cin >> n;
// 读取每个元素并加入优先队列
for (int i = 1; i <= n; i++) {
cin >> x;
q.push(x);
}
// 不断合并最小的两个元素,直到队列中只剩下一个元素
while (q.size() > 1) {
a = q.top();
q.pop();
b = q.top();
q.pop();
// 累加本次合并的成本
sum += (a + b);
// 将合并结果重新加入队列
q.push(a + b);
}
// 输出总成本
cout << sum;
return 0;
}
2.第k小
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, m, k;
cin >> n >> m >> k;
priority_queue<int> q;
for(int i = 0; i < n; i++){
int x;
cin >> x;
q.push(x);
}
while(m--)
{
while(q.size() > k) q.pop();
int x;
cin >> x;
if(x == 1){
int xx;
cin >> xx;
q.push(xx);
}
else{
if(q.size() >= k) cout << q.top() << endl;
else cout << -1 << endl;
}
}
}
3.简单的数据结构(双端队列)
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int N=200010;
int n,m;
deque<int> dq;
int main()
{
IOS;
scanf("%d%d",&n,&m);
while(m--)
{
int a,b;
scanf("%d",&a);
if(a==1)
{
scanf("%d",&b);
dq.push_front(b);
}
else if(a==2)
{
dq.pop_front();
}
else if(a==3)
{
scanf("%d",&b);
dq.push_back(b);
}
else if(a==4)
{
dq.pop_back();
}
else if(a==5)
{
reverse(dq.begin(),dq.end());
}
else if(a==6)
{
printf("%d\n",dq.size());
for(auto x:dq) printf("%d ",x);
printf("\n");
}
else if(a==7)
{
sort(dq.begin(),dq.end());
}
}
return 0;
}
4.新建Microsoft Office Word 文档
#include <bits/stdc++.h>
#define all(s) s.begin(), s.end()
using namespace std;
typedef vector<int> vi;
int n;
void solve() {
vi use(n + 1); //记录有没有这个数字
priority_queue<int, vi, greater<>> heap;
for(int i = 1; i <= n; ++ i) {
heap.emplace(i);
}
for(int i = 1; i <= n; ++ i) {
int x;
string op;
cin >> op;
if(op == "New") {
use[heap.top()] = 1;
cout << heap.top() << endl;
heap.pop();
}
else {
cin >> x;
if(!use[x]) {
cout << "Failed" << endl;
}
else {
cout << "Successful" << endl;
use[x] = 0;
heap.emplace(x);
}
}
}
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false), cout.tie(0);
int _ = 1;
// cin >> _ ;
while(_ -- ) {
cin >> n;
solve();
}
return 0;
}
四、并查集
1.Dong Dong 找亲戚
#include <bits/stdc++.h>
#include<queue>
using namespace std;
#define int long long
#define qw ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
int n,m;
map<string ,int >name;
//O(4)
const int maxn=20000;
int height[maxn+10];
int s[maxn+10];
void init_set()
{
for(int i=1;i<=maxn;i++)
{
s[i]=i;
height[i]=0;
}
}
int find_set(int x)
{
//路径压缩
int r=x;
while(s[r]!=r)
{
r=s[r];
}
int i=x,j;
while(i!=r)
{
j=s[i];
s[i]=r;
i=j;
}
return r;
}
void union_set(int x,int y)
{
//按秩合并
x=find_set(x);
y=find_set(y);
if(height[x]==height[y])
{
height[x]=height[x]+1;
s[y]=x;
}
else
{
if(height[x]<height[y])s[x]=y;
else s[y]=x;
}
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
string q;
cin>>q;
name[q]=i;
}
init_set();
for(int i=1;i<=m;i++)
{
int opt;
string x,y;
cin>>opt>>x>>y;
if(opt==1)
{
union_set(name[x],name[y]);
}
else
{
if(find_set(name[x])!=find_set(name[y]))cout<<0<<'\n';
else cout<<"1\n";
}
}
}
signed main()
{
qw;
int t=1;
//cin>>t;
while(t--)
{
solve();
}
}
2.洛谷P1551
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define up(l,r,i) for(int i=l; i<=r; i++)
using namespace std;
int f[10000];
int find(int x){
if(x == f[x]) return x;
return f[x] = find(f[x]);
}
int main()
{
int n, m, p, x, y;
cin >> n >> m >> p;
up(1,n,i){
f[i] = i;
}
up(1,m,i){
cin >> x >> y;
int xf, yf;
xf = find(x);
yf = find(y);
if(xf != yf) f[xf] = yf;
}
up(1,p,i){
cin >> x >> y;
int xf, yf;
xf = find(x);
yf = find(y);
if(xf == yf) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
3.洛谷P5266
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define up(l,r,i) for(int i=l; i<=r; i++)
using namespace std;
typedef long long ll;
map<string,int> a;
int main()
{
int n;
cin >> n;
up(1,n,i){
int op;
string name;
cin >> op;
if(op != 4) cin >> name;
switch(op){
case 1:
int score;
cin >> score;
a[name] = score;
cout << "OK\n";
break;
case 2:
if(a.count(name))
cout << a[name] << endl;
else cout << "Not found\n";
break;
case 3:
if(a.count(name)){
a.erase(name);
cout <<"Deleted successfully\n";
}else cout <<"Not found\n";
break;
case 4;
cout << a.size() << endl;
}
}
return 0;
}
4.P4305
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define up(l,r,i) for(int i=l; i<=r; i++)
#define dn(l,r,i) for(int i=l; i>=r; i--)
using namespace std;
typedef long long ll;
unordered_map<int, int> mp;
inline int read()
{
char c=getchar();int x=0,f=1;
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return x*f;
}
int main()
{
int _;
_ = read();
while(_--)
{
mp.clear();
int n, a;
n = read();
up(1,n,i){
a = read();
if(!mp[a]) {
mp[a] ++;
cout << a << " ";
}
}
if(_) cout << endl;
}
return 0;
}
5.P3879
记得查重
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define up(l,r,i) for(int i=l; i<=r; i++)
#define dn(l,r,i) for(int i=l; i>=r; i--)
using namespace std;
typedef long long ll;
const int maxn = 100001;
int n, m, num, cnt[maxn];
string s;
map<string,vector<int> >a;
int main()
{
std::ios::sync_with_stdio(false);//要关闭同步,快很多
cin>>n;
up(1,n,i)
{
cin>>num;
for(int j = 1; j <= num; j++)
{
cin>>s;
a[s].push_back(i);//vector的压入操作。我每一个单词就是一个vector。
}
}
cin>>m;
up(1,m,i)
{
cin>>s;
memset(cnt,0,sizeof(cnt));//cnt就是去重的桶。每用一次输出不同的查询要清零。
for(int j = 0; j < a[s].size(); j++)//a[s].size()是vector自动返回其长度的函数。
if(cnt[a[s][j]] == 0)
{
cout<<a[s][j]<<" ";//我们存的就是答案所求的所出现的句子的编号,所以直接输出不多bb。而且存的时候也是按顺序所记录的。
cnt[a[s][j]]++;//别忘了用桶去重!
}
cout<<endl;
}
return 0;
}
6.p3405
#include<bits/stdc++.h>
using namespace std;
int n,ans; //城市数 金币总数/答案
string a,b; //城市名 州名
map<string,int> box; //神奇的 map
int main()
{
ios::sync_with_stdio(false); //增加 cin, cout 的速度
cin>>n; //城市数量
while(n--) //重复 n 次
{
cin>>a>>b; //城市名 和 州名
a=a.substr(0,2); //取城市名称的前两位
if(a!=b) //特判 不能自己跟自己对应
ans+=box[a+b]; //取得金币/答案贡献
box[b+a]++; //存入金币,造福 城州名恰好相反的城市
}
cout<<ans<<endl;
return 0;
}
五、前缀和、差分
1.洛谷P2004
#include<bits/stdc++.h>
#define up(l,r,i) for(int i=l; i<=r; i++)
#define dn(l,r,i) for(int i=l; i>=r; i--)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll INf = 2147483647;
int a[1005][1005], b[1005][1005];
int main()
{
IOS;
int n, m, c, x, y;
cin >> n >> m >> c;
up(1,n,i){
up(1,m,j){
cin >> a[i][j];
b[i][j] = a[i][j] + b[i-1][j] + b[i][j-1] - b[i-1][j-1];
//这个地方很容易忘记减去b[i-1][j-1]
}
}
ll ans = -INf;
up(c,n,i){
up(c,m,j){
ll tmp = b[i][j]-b[i][j-c]-b[i-c][j]+b[i-c][j-c];
if(tmp > ans)
{
ans = tmp;
x = i, y = j;
}
}
}
cout << x-c+1 << " " << y-c+1;
return 0;
}
九、补题
1.
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define up(l,r,i) for(int i=l; i<=r; i++)
using namespace std;
int n, ans, sum;
stack<int> s;
struct node{
int val;
int pos;//原本在的位置
}shu[500010];
bool cmp1(node a, node b){
return a.val < b.val;
}
int gcd(int a, int b){
while(b!=0){
int c = b;
b = a%b;
a = c;
}
return abs(a);
}
int main()
{
IOS;
cin >> n;
up(1,n,i){
cin >> shu[i].val;
shu[i].pos = i;
}
sort(shu+1,shu+n+1,cmp1);
up(1,n,i){
int t = abs(i-shu[i].pos);
if(t != 0) s.push(t);
}
while(s.size() > 1)
{
int a = s.top();
s.pop();
int b = s.top();
s.pop();
ans = gcd(a,b);
s.push(ans);
}
if(s.size() == 1) ans = s.top();
up(1,ans,i){
if(ans % i == 0) sum ++;
}
if(sum == 0) sum = n;
cout << sum << endl;
return 0;
}
/*
找出原来那几个数应该排的位置和原来的位置的差值的绝对值(0不要),放进一个数组,找出这个数组的最大公约数,然后这个最大公约数的所有因数都符合。还有就是当所有的数字原来就排好,那么所有小于等于n的数字都符合要注意这个点
*/
2.k-bonacci
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
const int MOD = 1e9;
const int N = 1e6+5;
int a[N], b[N];
signed main()
{
IOS;
int n, k;
cin >> n >> k;
if(n < k) cout << 1;
else{
if(n == k) cout << k % MOD;
else{
for(int i=0; i<k; ++i)
{
a[i] = 1;
if(i > 0)
{
b[i] = a[i]%MOD + b[i-1]%MOD;
}else{
b[i] = 1;
}
//cout << a[i] << endl;
}
a[k] = k%MOD;
b[k] = a[k]%MOD + b[k-1]%MOD;
for(int i=k+1; i<=n; ++i)
{
a[i] = (b[i - 1] % MOD - b[i - k - 1] % MOD + MOD) % MOD;
b[i] = a[i]%MOD + b[i-1]%MOD;
//cout <<i<<" " <<a[i] << " " << b[i] << endl;
}
cout << a[n]%MOD;
}
}
return 0;
}
3.Codeforces Round 1021 (Div. 2) B. Sasha and the Apartment Purchase
/*
我们先排好序,然后可以枚举所有可能的数组,接着算出中位数的区间即可,但是如果枚举所有的可能是很慢的,经过观察,我们可以发现最后的情况就是:删除左边k个数得到剩余数的中位数(区间的右值) - 删除右边k个数得到剩余数的中位数(区间的左值)
所以结果就是 a[(n+k) / 2] - a[(n - k) / 2] + 1
特别的,由于我们的左值是要中位数的左边,所以最后其实是 a[(n+k) / 2] - a[(n - k - 1) / 2] + 1
比如6 2 / 5 1 9 10 13 2,操作就是
排序:1 2 5 9 10 13
右值:5 9 10 13,中位数就是 9 10 的右值,即 10
左值:1 2 5 9,中位数就是 9 10 的左值,即 2
结果就是 10 - 2 + 1 = 8,刚好对上样例
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.youkuaiyun.com/qq_61422664/article/details/147568114
*/
#include<bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
int n, k;
cin >> n >> k;
vector<int> a(n,0);
for(int i=0; i<n; i++)
{
cin >> a[i];
}
sort(a.begin(), a.end());
cout << a[(n+k)/2] - a[(n-k-1)/2] + 1 << endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while(t--)
{
solve();
}
return 0;
}
4.C. Sports Betting
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using llu = unsigned long long;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const ll MIN = -9187201950435737472ll;
ll mod = 1e9 + 7;
ll base = 131;
const int N = 1e4 + 10;
void solve()
{
int n;cin>>n;
vector<int>a(n+1,0);
map<int,int>mp;
for(int i=1;i<=n;i++)cin>>a[i],mp[a[i]]++;
sort(a.begin()+1,a.end());
a.erase(unique(a.begin()+1,a.end()),a.end());
int l=a.size()-1;
//cout<<l<<endl;
for(int i=1;i<=l;i++)
{
if(mp[a[i]]==1)continue;
if(mp[a[i]]>=4)
{
cout<<"Yes"<<endl;
return;
}
int j=i+1;
while(j<=l&&a[j]-1==a[j-1]&&mp[a[j]]<2)j++;
if(j==l+1)break;
if(a[j]-1==a[j-1]&&mp[a[j]]>1)
{
cout<<"Yes"<<endl;
return;
}
i=j-1;
}
cout<<"No"<<endl;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;cin>>t;
while (t--)
{
solve();
}
return 0;
}
5.Codeforces Round 1020 (Div. 3) B. St. Chroma
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
void solve()
{
int n, x;
cin >> n >> x;
if(n==1)
{
cout << "0\n";
return;
}
if(x >= n)
{
for (int i=0; i<n; i++)
{
cout << i << " ";
}
cout << endl;
return;
}
for (int i=0; i<x; i++) {
cout << i << " ";
}
for (int i=n-1; i>x; i--)
{
if(i != x) cout << i << " ";
}
cout << x << endl;
}
int main()
{
IOS;
int t;
cin >> t;
while(t--)
{
solve();
}
return 0;
}
6.Codeforces Round 1020 (Div. 3) C. Cherry Bomb
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
int a[200010], b[200010];
const int int_max = 1e9;
void solve()
{
int n, k;
cin >> n >> k;
int ma = 0;
int mi = int_max;
for (int i=1; i<=n; i++) {
cin >> a[i];
ma = max(a[i], ma);
mi = min(a[i], mi);
}
map<int,int> mp;
for (int i=1; i<=n; i++) {
cin >> b[i];
if(b[i]!=-1)
{
mp[b[i] + a[i]] ++;
}
}
if(mp.size() > 1) {
cout << 0 << endl;
}
if(mp.size() == 1)
{
int x;
for (map<int,int>::iterator it=mp.begin(); it!=mp.end();it++)
{
x = it->first;
}
if(x < ma || x-mi > k)
{
cout << 0 << endl;
}else{
cout << 1 << endl;
}
}
if(mp.size() == 0){
cout << k-(ma-mi)+1 << endl;
}
return;
}
int main()
{
IOS;
int t;
cin >> t;
while(t--)
{
solve();
}
return 0;
}
7.D. Flower Boy
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define llu unsigned long long;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const ll MIN = -9187201950435737472ll;
ll mod = 1e9 + 7;
ll base = 131;
const int N = 1e4 + 10;
void solve()
{
int n,m;
cin>>n>>m;
vector<ll>a(n+1),b(m+1);
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++)cin>>b[i];
int pos=1;
for(int i=1;i<=n;i++)
{
if(pos!=m+1 && a[i]>=b[pos])pos++;
}
if(pos==m+1)
{
cout<<0<<endl;
return;
}
vector<int>pre(n+1,0),suf(n+3,0);
int t=1;
for(int i=1;i<=n;i++)
{
int k=0;
if(a[i]>=b[t])t++,k=1;
pre[i]=pre[i-1]+k;
}
t=m;
for(int i=n;i>=0;i--)
{
int k=0;
if(a[i]>=b[t])t--,k=1;
suf[i]=suf[i+1]+k;
}
ll ans=1e18;
for(int i=1;i<=m;i++)
{
int pos=lower_bound(pre.begin(),pre.end(),i-1)-pre.begin();
//cout<<pos<<endl;
if(pos>n)continue;
if(pre[pos]==i-1&&suf[pos+1]>=m-i)ans=min(ans,b[i]);
}
if(ans==1e18)cout<<-1<<endl;
else cout<<ans<<endl;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;cin>>t;
while (t--)
{
solve();
}
return 0;
}
8.E. Wolf
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define llu unsigned long long
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const ll MIN = -9187201950435737472ll;
ll mod = 1e9 + 7;
ll base = 131;
const int N = 1e4 + 10;
void solve()
{
int n,q;
scanf("%d%d",&n,&q);
vector<int>p(n+1,0), st(n+1,0);
for(int i=1;i<=n;i++)
{
cin>>p[i];
st[p[i]]=i;
}
vector<int>ans;
while(q--)
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
if(st[x]<l||st[x]>r)
{
ans.push_back(-1);
continue;
}
if(l==r)
{
if(p[l]==x)ans.push_back(0);
else ans.push_back(-1);
continue;
}
int L=0,R=0,LL=0,RR=0;
while(l<r)
{
int mid=(l+r)/2;
if(p[mid]==x)break;
if(mid<st[x])
{
L++;
if(p[mid]<x)LL++;
l=mid+1;
}
else
{
R++;
if(p[mid]>x)RR++;
r=mid-1;
}
}
if(L>x-1||R>n-x)ans.push_back(-1);
else{
L-=LL;
R-=RR;
if(L>=R)
{
ll tmp=L-R;
if(x-1>=tmp+LL+R)ans.push_back(2ll*R+2ll*(L-R));
else ans.push_back(-1);
}
else
{
ll tmp=R-L;
if(n-x>=tmp+RR+L)ans.push_back(2ll*L+2ll*(R-L));
else ans.push_back(-1);
}
}
}
for(vector<int>::iterator y=ans.begin(); y!=ans.end(); y++)printf("%d ",*y);
printf("\n");
}
int main()
{
int t = 1;scanf("%d",&t);
while (t--)
solve();
return 0;
}
9.Codeforces Round 1023 (Div 2) EditorialC. Maximum Subarray Sum
#include<bits/stdc++.h>
// 关闭 C++ 输入输出与 C 语言输入输出的同步,加快输入输出速度
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
// 将 int 类型定义为 long long,避免整数溢出问题
#define int long long
using namespace std;
// 核心函数,用于解决每个测试用例
void solve()
{
int n;
long long k;
// 读取数组长度 n 和目标最大子数组和 k
cin >> n >> k;
string s;
// 读取字符串 s,用于标记可调整位置
cin >> s;
vector <long long> a(n);
// 读取数组 a 的每个元素
for (int i = 0; i < n; i++) cin >> a[i];
int pos = -1;
// 遍历字符串 s,找到第一个 '0' 对应的位置
for (int i = 0; i < n; i++){
if (s[i] == '0'){
pos = i;
// 将标记位置的值设为极小值,使其在首次计算最大子数组和时被忽略
a[i] = -1e13;
}
}
long long mx = 0;
long long curr = 0;
// 使用 Kadane 算法计算数组 a 的最大子数组和
for (int i = 0; i < n; i++){
// 更新当前子数组和
curr = max(curr + a[i], a[i]);
// 更新最大子数组和
mx = max(mx, curr);
}
// 如果最大子数组和超过 k,或者无法通过调整(无标记位置)达到 k
if (mx > k || (mx != k && pos == -1)){
cout << "No\n";
return;
}
// 存在可调整的标记位置
if (pos != -1){
mx = 0, curr = 0;
long long L, R;
// 计算标记位置右侧的最大子数组和 L
for (int i = pos + 1; i < n; i++){
curr += a[i];
mx = max(mx, curr);
}
L = mx;
mx = 0;
curr = 0;
// 计算标记位置左侧的最大子数组和 R
for (int i = pos - 1; i >= 0; i--){
curr += a[i];
mx = max(mx, curr);
}
R = mx;
// 调整标记位置的值,使整体最大子数组和为 k
a[pos] = k - L - R;
}
cout << "Yes\n";
// 输出调整后的数组
for (int i = 0; i < n; i++){
// 最后一个元素后输出换行,其他元素后输出空格
cout << a[i] << " \n"[i + 1 == n];
}
}
// 主函数,程序入口
signed main()
{
int t = 1;
// 读取测试用例数量 t
cin >> t;
// 循环处理每个测试用例
while(t--)
{
solve();
}
return 0;
}
十、其它
1.洛谷p1109
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define int long long
#define up(l,r,i) for(int i=l; i<=r; ++i)
using namespace std;
int n, a[51], b, c, all, l, r, ans;
signed main()
{
IOS;
cin >> n;
up(1,n,i) cin >> a[i];
cin >> l >> r;
up(1,n,i) al += a[i];
if(all < n*l || all > n*r){
cout << "-1";
return 0;
}
up(1,n,i) {
if(a[i] < l) {
b += (l-a[i]);
}
if(a[i] > r) c+=(a[i]-r);
}
cout << max(b,c);
return 0;
}
/*
读完题目,我们就应该知道:输出有两种情况,交换次数和 -1.
先考虑输出 -1 (即不能满足题目条件)的情况:
此时有两种可能,总人数(all)大于组数(n)乘上界(r)或小于组数乘下界(l)。代码实现很简单,求出总数再比较,满足条件输出 -1 。
然后是满足条件的情况:
用 b 数组存不足下限的组一共缺少的人数,用 c 数组存超过上限的组一共超过的人数。
最简单的方法就是用 c 数组中多出的人数去补 b 数组中缺少的人数,但如果 b,c 不相等呢?
当然要使 b,c 都等于0,所以最少交换次数就是 b,c 中较大的数
*/
2.洛谷p1145
#include<cstdio>
using namespace std;
int i,find,k,m,begin;
int check(int remain)
{
int result=(begin+m-1)%remain;
if(result>=k){//判断出列的那个人
begin=result;
return 1;
}
else{return 0;}
}
int main(){
scanf("%ld",&k);
m=k;
while(!find)
{
find=1;begin=0;//设置第一个
for(i=0;i<k;i++)
{
if(!check(2*k-i))//如果判断好,就可以退出了……
{
find=0;break;
}
}
m++;
}
printf("%d",m-1);//多加了一个,减回去
return 0;
}
3.洛谷p1165
#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
int n, f[200001], x, y, t=0;
signed main()
{
cin >> n;
f[0] = 0;
for (int i = 1; i <= n; ++i)
{
cin >> x;
if(!x){
cin >> y;
t ++;
f[t] = max(f[t-1], y);
}
if(x == 1) if(t!=0) t--;
if(x == 2) cout << f[t] << endl;
}
return 0;
}
4.P2021
#include<bits/stdc++.h>
using namespace std;
int n,now=2;
int a[1000001];
int main()
{
std::ios::sync_with_stdio(false);
cin>>n;
if(n==1){cout<<"1"<<endl; return 0;}//特判一下,比较快
for(int i=1;i<=n;++i)
{
if(!a[now]) a[now]=i;//这个位置是空的话就放进去
if(i==n) break;//如果放完了就可以退出了
int cnt=0;
while(cnt<2)//隔一个位置的的意义相当于找第二个空位
{
now++;
if(now>n) now-=n;//记得随时判断now指针是不是超过了n的长度限制
while(a[now])
{
now++;
if(now>n) now-=n;
}
cnt++;
}
}
for(int i=1;i<=n;++i) cout<<a[i]<<" ";
return 0;
}
5.p1105
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[1111], b[1111], c[1111];
signed main()
{
int n;
cin >> n;
for (int i=1; i<=n; ++i) {
cin >> a[i] >> b[i] >> c[i];
}
for (int i=1; i<=n; ++i) {
int t=0, s=0;
for (int j=1; j<=n; ++j) {
if(a[i]>a[j]&&b[i]>b[j]&&b[i]<c[j]){
if(a[t] < a[j]) t = j;
}
}
cout << t << " ";
for (int j=1; j<=n; ++j) {
if(a[i] > a[j]&&c[i] > b[j]&&c[i] < c[j]){
if(a[s] < a[j]) s = j;
}
}
cout << s << endl;
}
return 0;
}
6.
Description
TOM给自己定了一个宏伟的目标:连续100天每天坚持在zcmu上提交一个程序。100天过去了,tom查看自己的提交记录发现有N天因为贪玩忘记提交了。于是TOM要来M张"补提交卡"。每张"补提交卡"都可以补回一天的提交,将原本没有提交程序的一天变成有提交程序的一天。tom想知道通过利用这M张补提交卡,可以使自己的"最长连续提交天数"最多变成多少天。
Input
第一行是一个整数T(1 <= T <= 10),代表测试数据的组数。
每个测试数据第一行是2个整数N和M(0 <= N, M <= 100)。第二行包含N个整数,表示第a1, a2, ... aN天TOM没有提交程序。ai<=100
Output
对于每组数据,输出通过使用补提交卡TOM的最长连续提交天数最多变成多少。
Sample Input
3 5 1 34 77 82 83 84 5 2 10 30 55 56 90 5 10 10 30 55 56 90
Sample Output
76 59 100
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,i,sum,n,m;
int a[105]; scanf("%d",&t);
while(t--)
{
sum=0;a[0]=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
if(n<=m)
printf("100\n");
else
{
sum=a[m+1];
for(i=0;i<n-m;i++)
sum=max(sum,a[i+m+1]-a[i]);
sum=max(sum,100-a[n-m]);
if(sum==100-a[n-m])
printf("%d\n",sum);
else
printf("%d\n",sum-1);
}
}
}
7.洛谷p1465
#include<bits/stdc++.h>
using namespace std;
int n;
int i[20], v[20], x[20], l[20], c[20], d[20], m[20],A[20];
int ansi, ansv, ansx, ansl, ansc, ansd, ansm;
void mem(){
A[1] = 1; i[1] = 1;
A[2] = 4; i[2] = 1; v[2] = 1;
A[3] = 5; v[3] = 1;
A[4] = 9; i[4] = 1; x[4] = 1;
A[5] = 10; x[5] = 1;
A[6] = 40; x[6] = 1; l[6] = 1;
A[7] = 50; l[7] = 1;
A[8] = 90; x[8] = 1; c[8] = 1;
A[9] = 100; c[9] = 1;
A[10] = 400; c[10] = 1; d[10] = 1;
A[11] = 500; d[11] = 1;
A[12] = 900; c[12] = 1; m[12] = 1;
A[13] = 1000; m[13] = 1;
}
void add(int b, int num)
{
ansi += i[b]*num;
ansv += v[b]*num;
ansx += x[b]*num;
ansl += l[b]*num;
ansc += c[b]*num;
ansd += d[b]*num;
ansm += m[b]*num;
return;
}
int main()
{
scanf("%d", &n);
mem();
for(int j=1; j<=n; j++)
{
int temp = j, now = 13;
while(temp){
while(temp < A[now]) now--;
add(now, temp/A[now]);
temp %= A[now];
}
}
if(ansi != 0) printf("I %d\n", ansi);
if(ansv != 0) printf("V %d\n", ansv);
if(ansx != 0) printf("X %d\n", ansx);
if(ansl != 0) printf("L %d\n", ansl);
if(ansc != 0) printf("C %d\n", ansc);
if(ansd != 0) printf("D %d\n", ansd);
if(ansm != 0) printf("M %d\n", ansm);
return 0;
}
十一、分治
1.
#include <bits/stdc++.h> // 包含所有标准头文件(方便但非标准,竞赛常用)
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) // 加速输入输出
using namespace std;
int n; // 输入的迭代次数
char a[3000][3000]; // 存储分形图案的二维数组(足够大以容纳n次迭代后的图案)
int h = 2, w = 4; // 初始图案的高度和宽度(基础图案为2行4列)
int main() {
IOS; // 应用输入输出加速宏
cin >> n; // 读取迭代次数n
memset(a, ' ', sizeof(a)); // 初始化数组为空格字符,sizeof(a)按二维数组总大小计算
// 初始化基础图案(n=1时的图案)
// 第1行:空格 / \ 空格 → 视觉上是" /\"
a[1][1] = ' '; a[1][4] = ' '; // 左右边界留空
a[1][2] = '/'; a[1][3] = '\\'; // 上边缘的斜杠
// 第2行:/ __ \ → 视觉上是"/__\"
a[2][1] = '/'; a[2][4] = '\\'; // 下边缘的斜杠
a[2][2] = '_'; a[2][3] = '_'; // 中间的下划线
// 分形迭代:从n=2开始,执行n-1次扩展(n=1时不进入循环)
for (int i = 1; i < n; ++i) { // i表示当前迭代次数,从1到n-1
// 第一步:将当前图案复制到下方,并清空原位置
// 目的:为生成更大的分形图案腾出上方空间,下方存储左右两个子图案
for (int j = 1; j <= h; ++j) { // 遍历当前所有行(j从1到h)
for (int k = 1; k <= w; ++k) { // 遍历当前所有列(k从1到w)
// 复制到下方h行的左右两侧,间隔w列(形成左右两个子图案)
a[j + h][k] = a[j][k]; // 下方左侧:行号+h,列号不变
a[j + h][k + w] = a[j][k]; // 下方右侧:行号+h,列号+当前宽度w
a[j][k] = ' '; // 清空原位置,准备绘制中间连接部分
}
}
// 第二步:将下方左侧的子图案移动到当前行的中间位置,形成分形连接
// 目的:在上下子图案之间填充连接符(斜杠和下划线)
for (int j = 1; j <= h; ++j) { // 遍历当前行(此时还是原高度h,尚未更新)
for (int k = 1; k <= w; ++k) { // 遍历当前列
// 中间位置为当前列 + 宽度的一半(w/2),将下方左侧子图案移动到中间
a[j][k + w / 2] = a[j + h][k]; // 从下方左侧(j+h行k列)复制到当前行中间位置
}
}
// 更新图案尺寸:高度和宽度翻倍,为下一次迭代做准备
w *= 2; h *= 2; // 分形图案的规模按指数级增长
}
// 输出最终生成的分形图案
for (int i = 1; i <= h; ++i) { // 遍历所有行(i从1到h)
for (int j = 1; j <= w; ++j) { // 遍历所有列(j从1到w)
cout << a[i][j]; // 输出当前字符
}
cout << endl; // 换行,输出完一行
}
return 0;
}