一些题。。

一.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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值