700题复习计划

review

AT193

将n个数从小到大排序,挨个输出

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
string a[105];
int n,m;
bool cmp(string x,string y){
    return x+y>y+x;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++){
        cout<<a[i];
    }
    cout<<"\n";
    return 0;
}

CF898D

将闹钟响的时间排序,枚举 \(i\),如果 \(a_i\)\(a_i + m\) 这个区间内有大于k 个闹钟的话,就贪心将后面的删去,直到这个区间内只有 k 个为止

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};

const int N = 2e5 + 10, M = 1e6 + 10;

int n, m, k;
int a[N], cnt;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    cin >> n >> m >> k;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    sort(a + 1, a + n + 1);
    
    deque<int> dq;
    
    for (int i = 1; i <= n; ++i)
    {
        while (dq.size() && dq.front() <= a[i] - m)
            dq.pop_front();
        dq.push_back(a[i]);
        while (dq.size() >= k)
            ++cnt, dq.pop_back();
    }
    cout << cnt << endl;
    return 0;
}
//

CF898C

将每一个人的号码排序,判断是否存在后缀的情况,有就删,没有就保留

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 25;

map<string,vector<string> >mp;
bool cmp(string s1,string s2)
{
    return s1<s2;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    string name,ss;
    for(int i=1; i<=n; i++)
    {
        cin>>name;
        int m;
        cin>>m;
        while(m--)
        {
            cin>>ss;
            reverse(ss.begin(),ss.end());//先翻转存入便于判断后缀
            mp[name].push_back(ss);
        }
    }
    cout<<mp.size()<<endl;
    map<string,vector<string> >::iterator it;
    for(it=mp.begin(); it!=mp.end(); it++)
    {
        string str[1000],ans[1000];
        cout<<it->first<<" ";
        vector<string>v=it->second;
        int len=v.size();
        for(int i=0; i<len; i++)
        {
            str[i]=v[i];
        }
        sort(str,str+len,cmp);
        int i,j,k=0;
        for(i=0; i<len; i++)
        {
            int temp,flag=0;
            for(j=i+1; j<len; j++)
            {
                temp=str[j].find(str[i]);
                if(temp==0)
                {
                    flag=1;
                    break;
                }
            }
            if(flag==0)
            {
                ans[++k]=str[i];
            }
        }
        cout<<k;
        for(int i=1; i<=k; i++)
        {
            reverse(ans[i].begin(),ans[i].end());
            cout<<" "<<ans[i];
        }
        cout<<endl;
    }
}
//

CF898B

枚举 \(x\) ,二分 \((n - a \times x) \mod b\) 是否等于 0

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    int n,a,b;
    cin>>n>>a>>b;

    for(int i=0;i<=n/a;i++)
        if((n - i * a) % b == 0)
        {
            cout<<"YES"<<endl;
            cout<<i<<' '<<(n - a * i) / b;
            return 0;
        }

    cout<<"NO";

    return 0;
}
//

CF877E

\(dfs\)序来找到子树,一个子树作为一段来建线段树

#include <bits/stdc++.h>
using namespace std;

const int N = 200005;
struct Tree
{
	int l,r;
	int turn;
	int sum;
	int mid;
} tr[N * 4];

vector<int> g[N];//存图

int in[N],out[N],order[N],times = 0;// 进入栈的时间,出栈的时间,dfs序,当前时间
void dfs(int root,int father)
{
	in[root] = ++times;
	order[times] = root;

	int len = g[root].size();
	for(int i=0; i<len; i++)
	{
		int v = g[root][i];
		if(v == father) continue;
		dfs(v,root);
	}

	out[root] = times;
}

void pushup(int u)
{
	tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}

void pushdown(int u)
{
	if(tr[u].turn)
	{
		tr[u<<1].turn ^= 1, tr[u<<1|1].turn ^= 1;
		tr[u<<1].sum = tr[u<<1].r - tr[u<<1].l + 1 - tr[u<<1].sum;// xor
		tr[u<<1|1].sum = tr[u<<1|1].r - tr[u<<1|1].l + 1 - tr[u<<1|1].sum;// xor
		tr[u].turn = 0;
	}
}

int w[N];//原开关情况
void build(int u,int l,int r)
{
	if(l == r) tr[u].l = l,tr[u].r = r,tr[u].turn = 0,tr[u].sum = w[order[l]];
	else
	{
		tr[u].l = l,tr[u].r = r,tr[u].turn = 0;
		int mid = l + r >> 1;
		tr[u].mid = mid;

		build(u<<1,l,mid);
		build(u<<1|1,mid+1,r);
		pushup(u);
	}
}

void modify(int u,int l,int r)
{
	if(tr[u].l >= l && tr[u].r <= r)
	{
		tr[u].sum = tr[u].r - tr[u].l + 1 - tr[u].sum; // xor
		tr[u].turn ^= 1;
	}
	else
	{
		pushdown(u);
		if(l <= tr[u].mid) modify(u<<1,l,r);
		if(r > tr[u].mid) modify(u<<1|1,l,r);
		pushup(u);
	}
}

int query(int u,int l,int r)
{
	if(tr[u].r < l || tr[u].l > r) return 0;
	if(tr[u].l >= l && r >= tr[u].r) return tr[u].sum;

	pushdown(u);
	int res = 0;

	if(l <= tr[u].mid) res += query(u<<1,l,r);
	if(r > tr[u].mid) res += query(u<<1|1,l,r);

	pushup(u);

	return res;
}

int main()
{
	int n;
	cin>>n;
	for(int i=2; i<=n; i++)
	{
		int x;
		scanf("%d",&x);
		g[x].push_back(i);
		g[i].push_back(x);
	}
	for(int i=1; i<=n; i++) scanf("%d",&w[i]);

	dfs(1,-1);
	build(1,1,n);

	int q;
	scanf("%d",&q);
	while(q--)
	{
		char opt[4];
		int x;
		scanf("%s%d",opt,&x);

		if(opt[0] == 'p') modify(1,in[x],out[x]);
		else cout << query(1,in[x],out[x]) << endl;
	}

	return 0;
}
//

CF787B

如果一个团队中没有出现绝对值相同的两个数,就是YES,否则NO

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 1e4+10;

unordered_map<int,int> t;

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	int n,m;
	cin>>n>>m;

	for(int i=1;i<=m;i++)
	{
		int k;
		cin>>k;

		t.clear();

		bool flag = 0;
		for(int i=1;i<=k;i++)
		{
			int x;
			cin>>x;
			t[x] = 1;
			if(t[-x])
			{
				flag = 1;
			}
		}
		if(!flag) 
		{
			cout<<"YES";
			return 0;
		}
	}

	cout<<"NO";

    return 0;
}
//

CF776B

质数为1,否则为2

#include <bits/stdc++.h>
using namespace std;

const int N = 100005;

bool st[N];
int prime[N],cnt=0;

void gets_prime(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) prime[cnt++] = i;
        for(int j=0;prime[j] <= n/i;j++)
        {
            st[prime[j] * i] = 1;
            if(i % prime[j] == 0) break;
        }
    }
    
    return ;
}
int main()
{
	int n;
	cin>>n;
	
	gets_prime(n+2); 
	
	if(n < 3) cout<<1<<endl;
	else cout<<2<<endl;
 
 
 	for(int i=2;i<=n+1;i++)
 	{
 		if(st[i]) cout<<2<<' ';
 		else cout<<1<<' ';
	}
	
	return 0;
} 

CF734C

考虑不用药,\(ans = n * w\)

考虑只用第一种药,如果\(b[i]\le s\),就更新答案 \(ans = min(ans,n * a[i])\)

考虑只用第二种药,如果\(d[i]\le s\),就更新答案 \(ans = min(ans,(n-c[i]))\)

考虑先用第一种药,再在d中二分出 \(x\)\(s - b[i]\) 的位置, \(ans = min(ans, (n-c[x]) * a[i]\)

#include <bits/stdc++.h>
using namespace std;

const int INF= 0x3f3f3f3f;
const int N=2e5+5;
typedef long long LL;

LL n,m,k,w,s;
LL b[N],c[N];

struct Node
{
	LL x;
	LL y;
} a[N];

int main()
{
	scanf("%d%d%d%d%d",&n,&m,&k,&w,&s);
	for(int i=1; i<=m; i++) scanf("%d",&a[i].x);
	for(int i=1; i<=m; i++) scanf("%d",&a[i].y);
	for(int i=1; i<=k; i++) scanf("%d",&b[i]);
	for(int i=1; i<=k; i++) scanf("%d",&c[i]);

	LL time=n*w;
	for(int i=1; i<=k; i++)
	{
		if(c[i] <= s)
		{
			time=min(time, (n-b[i])*w );
		}
	}
	for(int i=1; i<=m; i++)
	{
		if(a[i].y <= s)
		{
			time=min(time, n*a[i].x );
		}
	}
	for(int i=1; i<=m; i++)
	{
		if(a[i].y > s) continue;

		LL aa=upper_bound(c+1,c+1+k, s-a[i].y )-(c+1);
		if(c[aa] <= s-a[i].y)
			time=min(time, (n-b[aa])*a[i].x) ;
	}
	
	cout<<time;

	return 0;
}

CF898A

将一个数四舍五入。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    int n;
    cin>>n;

    int a = n % 10;
    int b = 10 - (n % 10);

    if(a < b) cout<<n - a;
    else cout<< n + b;

    return 0;
}
//

CF811A

模拟,实在没啥可以解释的

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int a,b;
    cin>>a>>b;
    
    int k = 1;
    while(1)
    {
        if(a < k) 
        {
            cout<<"Vladik"<<endl;
            break;
        }
        a -= k;
        k++;
        if(b < k)
        {
            cout<<"Valera"<<endl;
            break;
        }
        b -= k;
        k ++;
    }

    return 0;
}

CF808A

所有的lucky year都可以表示为 \(j * 10^i\) ,枚举 \(i\)\(j\) 即可。

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    for(int i=1;;i*=10)
    {
        bool flag = 0;
        for(int j=1;j<=9;j++)
        {
            if(i * j > n)
            {
                cout<<i*j-n<<endl;
                flag = 1;
                break;
            }
        }
    
        if(flag) break;
    }
    
    return 0;
}

CF787A

枚举时刻 \(i\), 当 \((i - b) \mod a == 0 \; and \;(i - d) \mod c == 0\) 即输出i

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	int a,b,c,d;
	cin>>a>>b>>c>>d;

	for(int i=0;i<=100000000;i++)
	{
		if(i-b >= 0 && i-d >= 0 && (i - b) % a == 0 && (i - d) % c == 0) 
		{
			cout<<i;
			return 0;
		}
	}

	cout<<-1;

    return 0;
}
//

CF786A

现在我们知道 1 是必败态,那么我们通过 \(DFS\) 可以判断每个点的胜负情况、是否有解。

我们考虑逆向思维,对每个玩家在 1 时的先手状态向前转移,具体过程如下:

  1. 定义 \(DFS(v,now)\) 表示现在是 \(now\)的位置,玩家 \(v\) 先手。
  2. 枚举上一次玩家 \(u\) 的操作 \(x\),那么可以从 \(now-x\) 的位置转移到 \(now\) 的位置(注意这里的 \(now-x\) 不能等于 \(1\))。
  3. 如果 \(now\) 的位置是必败态,那么根据结论:能转移到必败态的状态就是必胜态,可以得到 \(now-x\) 的位置是必胜态。
  4. 如果 \(now\) 的位置是必胜态,那么根据结论:只能转移到必胜态的状态就是必败态。我们记 \(cnt_{u,i}\) , \(i\) 表示在\(i\) 这个位置且 u 先手可以转移到的必胜态数量。当 \(cnt_{u,now-x}+1=k_u\),时,意味着从 \((u,now-x)\) 转移到的所有状态都是必胜态,那么意味着从 \((u,now-x)\) 这个状态为必败态。
  5. 继续 \(DFS(u,now-x)\) 进行转移即可。
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 7005;

int k[2];
int cnt[2][N];
int step[2][N];
bool vis[2][N],win[2][N];
int n;

void dfs(int user,int pos)
{
	if(vis[user][pos]) return ;
	vis[user][pos] = 1;
	int u = user ^ 1;

	for(int i=1;i<=k[u];i++)
	{
		int pre = (pos - step[u][i] + n - 1) % n + 1;

		if(pre == 1) continue;
		if(!win[user][pos])
		{
			win[u][pre] = 1;
			dfs(u,pre);
		}
		else if(++cnt[u][pre] == k[u])
		{
			win[u][pre] = 0;
			dfs(u,pre);
		}
	}
}

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	cin>>n;
	for(int i=0;i<=1;i++)
	{
		cin>>k[i];
		for(int j=1;j<=k[i];j++)
			cin>>step[i][j];
	}


	dfs(0,1);
	dfs(1,1);

	for(int i=0;i<=1;i++) 
	{
		for(int j=2;j<=n;j++)
		{
			if(!vis[i][j]) cout<<"Loop ";
			else if(win[i][j]) cout<<"Win ";
			else cout<<"Lose ";
		}
		cout<<endl;
	}

    return 0;
}
//

CF701B

可以将车平移到四周,类似数学中的一块草地,要在上面铺路,求草地面积。

开个col,row数组记录这一列,行有没有被攻击。

如果新增的车的那一列,行没有攻击过,则n--,或m--

最后输出n * m

#include <bits/stdc++.h>
using namespace std;

const int N = 100005;

bool row[N];
bool col[N];

int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	
	long long num_row = n,num_col = n;
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		if(!row[x]) row[x] = 1,num_row --;
		if(!col[y]) col[y] = 1,num_col --;
		
		cout<<num_row*num_col<<endl;
	}
	
	return 0;
}
//

CF701A

排序,a[i] 和 a[n - i + 1] 为一对

#include <bits/stdc++.h>
using namespace std;

const int N = 105;

struct Node
{
	int val;
	int id;
	
	bool operator < (const Node& x) const
	{
		return val < x.val;
	}
}a[N];

int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i].val,a[i].id=i;
	
	sort(a+1,a+1+n);
	
	for(int i=1;i<=n/2;i++)
		cout<<a[i].id<<' '<<a[n-i+1].id<<endl;
	
	return 0;
}

CF664A

如果 a==b ,则为a,否则为1

#include <bits/stdc++.h>
using namespace std;

int main()
{
    string a,b;
    cin>>a>>b;
    
    if(a==b) cout<<a;
    else cout<<1;
    
    return 0;
}

CF608B

处理出 b 的前缀和

如果a[i] == 1,就和b[i.i + n - 1],ans 加上b中以i为左端点,长度为m的区间内0的个数

反之亦然

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 200005;
char a[N],b[N];
int sum[N];

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    cin>>a+1>>b+1;

    int n = strlen(a + 1), m = strlen(b + 1);
    for(int i=1;i<=m;i++) sum[i] = sum[i-1] + (b[i] == '0');

    LL ans = 0;
    for(int i=1;i<=n;i++) 
    {
        if(a[i] == '1') ans += sum[m - (n - i)] - sum[i - 1];
        else ans += m - n + i  - sum[m - (n - i)] - i + 1 + sum[i-1]; 
    }

    cout<<ans;

    return 0;
}

CF608A

记录从第i楼出发的乘客的到达时间的最大值

从上到下枚举楼层,如果当前这一层楼的所有乘客都到了。就直接下楼 —— ans++

否则就等到乘客到了位置,再下楼——ans = max(ans,f[i]) + 1

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 1005;

int n,s,x;
int f[N],t[N];

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	cin>>n>>s;
    for(int i=1;i<=n;i++) cin>>x>>t[i],f[x] = max(f[x],t[i]);

    int ans = 0;
    for(int i=s;i>=1;i--)
    {
        ans = max(ans,f[i]);
        ans ++;
    }

    cout<<ans;

    return 0;
}
//

CF606B

阅读题

按照给出的序列走,问第k次走到的点在之前是否走过,并问最后的时候有多少个点没有走过

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 5005;

int n,m;
int x,y;
string s;
bool st[N][N];

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    cin>>n>>m>>x>>y;
    cin>>s;
    
    int len = s.size(), cnt = 1;
    st[x][y] = 1;
    cout<<1<<' ';
    for(int i=0;i<len-1;i++)
    {
        if(s[i] == 'U' && x > 1) x--;
        if(s[i] == 'D' && x < n) x ++;
        if(s[i] == 'L' && y > 1) y --;
        if(s[i] == 'R' && y < m) y ++;

        if(!st[x][y]) cout<<1<<' ',cnt++;
        else cout<<0<<' ';
        st[x][y] = 1;
    }

    cout << n * m - cnt;

    return 0;
}
//

CF606A

每两个同色剩余可以换一个欠的

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;

int a[5],b[5],c[5];

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    int n = 3;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];

    int add = 0,sub = 0;
    for(int i=1;i<=n;i++) c[i] = a[i] - b[i];
    for(int i=1;i<=n;i++) 
    {
        if(c[i] < 0) sub += c[i];
        if(c[i] > 0) add += c[i] / 2;
    }

    // cout<<add<<' '<<sub<<endl;

    if(add + sub >= 0) cout<<"Yes";
    else cout<<"No";

    return 0;
}
//

CF554B

如果这两行是一样的,整列翻转只有长的也一样

#include <bits/stdc++.h>
using namespace std;

unordered_map<string,int> h;
string s;

int main()
{
    int n;
    cin>>n;
    
    for(int i=1;i<=n;i++) cin>>s,h[s]++;
    
    int res = 0;
    for(auto x : h) 
        res = max(res,x.second);
        
    cout<<res;
    
    return 0;
}

CF456B

\((1^n + 2^n + 3^n + 4^n) \mod 5 = (1^n \mod 5 + 2^n \mod 5 + 3^n \mod 5 + 4^n \mod 5) \mod 5\)

根据费马小定理:\(a^{5-1} \equiv 1 (mod \;5)\)

所以原式 $ = (1^{n; mod;4} + 2^{n; mod;4} + 3^{n; mod;4} + 4^{n; mod;4}) \mod 5$

最后打个高精模吗,搞定

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;


int mod(string a,int b)//高精度a除以单精度b
{
    int d=0;
    for(int i=0;i<a.size();i++)  d=(d*10+(a[i]-'0'))%b;  //求出余数
    return d;
}

int power(int x,int y)
{
    int ans = 1;
    for(int i=1;i<=y;i++) ans *= x;
    return ans;
}

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	string n;
    cin>>n;

    int mi = mod(n,4);

    LL ans = (power(2,mi) % 5 + power(3,mi) % 5 + power(4,mi) + 1) % 5;

    cout<<ans;

    return 0;
}
//

CF456A

按价格排序,维护质量前缀最大值,发现前缀最大值比 \(b_i\) 大,就Happy,反之亦然

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 1e5;

PII a[N];
int n;

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i].first>>a[i].second;

    sort(a+1,a+1+n);

    for(int i=1;i<n;i++)
    {
        if(a[i].first < a[i+1].first && a[i].second > a[i+1].second)
        {
            cout<<"Happy Alex";
            return 0;
        }
    }

    cout<<"Poor Alex";

    return 0;
} 
//

CF455B

判断前缀可以用Trie解决

如果根节点有必胜策略,也有必败策略,则倒数第二局必败的就可以在最后一局必胜,如此类推,第一局的先手必胜

如果根节点有必胜策略,没有必败策略,则如果局数为奇数,第一局的先手必胜,否则必败

如果根节点没有必胜策略,但有必败策略,那么每一局都是后手胜利,所以最后是后手胜利

求出所有点是否有必胜态和必败态,最后根据上面的几种情况求出答案

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 1e6 + 10;

int trie[N][26],cnt;
int sg[N];//1 win, 2 lose, 3 up to you, 4 not sure
int n, m;

void insert(string s)
{
    int u = 0, len = s.size();
    for(int i=0;i<len;i++)
    {
        int v = s[i] - 'a';
        if(!trie[u][v]) trie[u][v] = ++cnt; 
        u = trie[u][v];
    }
}

void dfs(int u)
{
    bool win = 0;
    bool lose = 0;
    bool flag = 1;//是否为前缀

    for(int i=0;i<26;i++)
    {
        if(trie[u][i])
        {
            dfs(trie[u][i]);
            if(sg[trie[u][i]]==1||sg[trie[u][i]]==4)
				win=1;
			if(sg[trie[u][i]]==2||sg[trie[u][i]]==4)
				lose=1; 
			flag=0;
        }
        if(flag) sg[u] = 1;
        else 
        {
            if(win && lose) sg[u] = 3;
            else if(win) sg[u] = 2;
            else if(lose) sg[u] = 1;
            else sg[u] = 4;
        }
    }
}

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        string s;
        cin>>s;
        insert(s);
    }

    dfs(0);

    if(sg[0]==1) puts("Second");
	else if(sg[0]==2)
		if(m&1) puts("First");
		else puts("Second");
	else if(sg[0]==3) puts("First");
	else puts("Second");

    return 0;
}

CF455A

DP

\(f[i]\) 为删数值为 i 时的最大价值,桶 t[i] 为数值为 \(i\) 的数出现的次数

如果 \(f[i]\) 是被 \(i-1\) 通过 \((i-1)+1\) 被删的,价值为 \(f[i-1]\)

否则不删 \(i-1\) 的话一定会删 \(i\)\(i-2\) (否则就一定不是最佳答案)价值为 f[i-2] + i * t[i]

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> PII;

const double PI = 3.1415926535;
const LL Mod = 1e9 + 7;
const LL INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const LL dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const LL dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const LL pow10[15] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};

const LL N = 1e5 + 10;

int n, a[N];
LL dp[N];

int main()
{
    cin >> n;
    while (n--)
    {
        int x;
        cin >> x;
        a[x]++;
    }
    for (int i = 1; i <= 100000; i++)
    {
        if (a[i]) dp[i] = dp[i - 2] + 1ll * a[i] * i;
        dp[i] = max(dp[i], dp[i - 1]);
    }
    
    cout << dp[100000];
	
    return 0;
}

CF454B

找到最大的值所在的位置,如果最大值在最后一位,就是不需要移动

最大值的位置++则为理论最小值的位置,再向后找比他大的,如果最后的指针不在n-1处,或者最后一位比第一位要大,就是不合法的,否则合法

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};

const int N = 1e5 + 10;

int a[N];

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i <= n - 1; ++i)
        cin >> a[i];
    int i = 0, j = 0;
    while (a[i] <= a[i + 1])
        ++i;
    if (i == n - 1)
    {
        cout << 0;
        return 0;
    }
    ++i;
    ++j;
    while (a[i] <= a[i + 1])
    {
        ++i;
        ++j;
    }
    if (i != n - 1)
    {
        cout << -1;
        return 0;
    }
    else if (a[n - 1] > a[0])
    {
        cout << -1;
        return 0;
    }
    else
        cout << j;
    return 0;
}
//

CF454A

直接模拟

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	int n;
    cin>>n;

    for(int i=0;i<n/2;i++)
    {
        for(int j=0;j<(n-i*2+1)/2-1;j++) cout<<'*';
        for(int j=0;j<i*2+1;j++) cout<<'D';
        for(int j=0;j<(n-i*2+1)/2-1;j++) cout<<'*';
        cout<<endl;
    }

    for(int i=1;i<=n;i++) cout<<'D';
    cout<<endl;

    for(int i=n/2-1;i>=0;i--)
    {
        for(int j=0;j<(n-i*2+1)/2-1;j++) cout<<'*';
        for(int j=0;j<i*2+1;j++) cout<<'D';
        for(int j=0;j<(n-i*2+1)/2-1;j++) cout<<'*';
        cout<<endl;
    }

    return 0;
}
//

CF453A

期望 = 概率 * 权值

如果投 n 次,最大点数为 i

如果 n 次投的点数在1~k中,共有 \(k^n\) 种情况

如果 n 次投的点数在1~k-1中,共有 \((k-1)^n\) 种情况

这 n 次投掷中有 k 的有 \(k^n - (k-1)^n\) 种情况,概率为\(\frac{k^n - (k-1)^n}{k^n}\)

最后的期望$ = \frac{\sum_{i=1}^{m} i \times (i^n - (i-1)n)}{mn} $

#include<cstdio>
#include<cmath>
using namespace std;
double n,m,ans;
int main(){
	scanf("%lf%lf",&m,&n);
	for(double i=1;i<=m;i++)
	ans+=i*(pow(i/m,n)-pow((i-1)/m,n));
	printf("%.12lf\n",ans);
}

CF45A

输出 (当前月份 + n) % 12 的月份

#include <bits/stdc++.h>
using namespace std;

string month[13]={"January","February","March","April","May","June","July","August","September","October","November","December"};

int get(string str)
{
	for(int i=0;i<12;i++) if(month[i]==str) return i;
}

string to_str(int i)
{
	return month[i];
}

int main()
{
	string str;
	int n;

	cin>>str>>n;

	int start=get(str);
	int ans=(start+n)%12;

	cout<<to_str(ans);

	return 0;
}

CF20C

无向图最短路径,直接dijkstra+记录路径,递归输出

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> PII;

const double PI = 3.1415926535;
const LL Mod = 1e9 + 7;
const LL INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const LL dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const LL dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const LL pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const LL N = 1e5 + 10;

struct Edge
{
    LL v,w,nxt;
}e[N * 2];
LL head[N];

priority_queue<PII,vector<PII>,greater<PII>> h;
LL n,m;

LL idx = 0;
void add(LL u,LL v,LL w)
{
    e[++idx].v = v;
    e[idx].w = w;
    e[idx].nxt = head[u];
    head[u] = idx;
}

bool st[N];
LL dis[N];
LL pre[N];
LL dijkstra(LL start,LL dest)
{
    memset(dis,0x3f,sizeof dis);
    dis[start] = 0;
    h.push({0,1});

    while(!h.empty())
    {
        LL u = h.top().second,disu = h.top().first;
        h.pop();
        if(st[u]) continue;
        
        st[u] = 1;

        for(LL j=head[u];j;j=e[j].nxt)
        {
            LL v = e[j].v, w = e[j].w;
            if(dis[v] > disu + w)
            {
                dis[v] = disu + w;
                pre[v] = u;
                h.push({dis[v],v});
            }
        }
    }
    return dis[dest];
}

void dfs(LL t, LL x, LL cnt) 
{ //当前点x到起点t的最短路径
	if (pre[x] != 0) 
    {
		dfs(t, pre[x], cnt + 1);
		printf("%lld%c", x, cnt == 1 ? '\n' : ' ');
	}
	else printf("%lld%c", t, ' ');
}

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    cin>>n>>m;

    for(LL i=1;i<=m;i++)
    {
        LL u,v,w;
        cin>>u>>v>>w;
        add(u,v,w);
        add(v,u,w);
    }

    LL ans = dijkstra(1,n);
    if(ans == LNF) cout<<-1;
    else dfs(1,n,1);

    return 0;
}
//

CF9A

概率论,取两人的最大值max, 答案为 \(\frac{6 - max }{6}\)

最后上下同除gcd

#include <iostream>
using namespace std;

int main()
{
	int a,b,c;
	cin>>a>>b;

	c=max(a,b);

	if(c==1)
		cout<<"1/1";	//一定能赢
	if(c==6)
		cout<<"1/6";
	if(c==5)
		cout<<"1/3";
	if(c==4)
		cout<<"1/2";
	if(c==3)
		cout<<"2/3";
	if(c==2)
		cout<<"5/6";

	return 0;
}

CF4A

所有大于4的偶数都可以

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int main()
{
	int n;
	cin>>n;
	if(n%2==0&&n!=2)
	{
		cout<<"YES";
		return 0;
	}
	cout<<"NO";
	return 0;
}

CF2A

开个map维护信息

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;

const int N = 1005;

map<string,int> hash_map;//哈希表

int n;
string name[N];//名字
int sorce[N];//分数

map<string,int> temp;//统计谁先到达最大分数的时候用的

int main()
{
    ios::sync_with_stdio(0);

    cin>>n;

    for(int i=1;i<=n;i++) 
    {
        cin>>name[i]>>sorce[i];
        hash_map[name[i]] += sorce[i];
    }

    int maxx = -0x3f3f3f3f;
    for(int i=1;i<=n;i++) maxx = max(maxx,hash_map[name[i]]);

    for(int i=1;i<=n;i++)
    {
        temp[name[i]] += sorce[i];
        if(temp[name[i]] >= maxx && hash_map[name[i]] == maxx) 
        {
            cout<<name[i]<<endl;
            return 0;
        }
    }

    return 0;
}

CF1A

求长和宽除以a上取整,相乘

#include <iostream>
using namespace std;
int main()
{
	long long a,m,n;
	cin>>n>>m>>a;
	cout<<((n-1)/a+1)*((m-1)/a+1);
	return 0;
}

CF954B

枚举复制串的长度,判断是否可以复制,可以就更新答案

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;
char s[105];

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	int n;

	scanf("%d%s",&n,s+1);

	int ans = n;
	for(int i=1;i<=n/2;i++)
	{
		bool flag = 0;
		for(int j=i+1;j<=i+i;j++)
		{
			if(s[j-i] != s[j]) 
			{
				flag = 1;
				break;
			}
		}

		if(!flag) ans = min(ans, n - i + 1);
	}

	cout<<ans;

    return 0;
}
//

CF954A

贪心,遇到 RU 或 UR 就换成 D

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	int n;
	string a;
	cin>>n>>a;

	a += ' ';

	int ans = 0;
	for(int i=0;i<a.size()-1;i++)
	{
		if(a[i] == 'R' && a[i+1] == 'U') ans ++,i++;
		else if(a[i] == 'U' && a[i+1] == 'R') ans ++,i++;
		else ans ++;
	}

	cout<<ans;

    return 0;
}

//

CF1005B

求最长公共后缀

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};

const int N = 0;

int main()
{
    ios::sync_with_stdio(0);
    
    string s,t;
    cin>>s>>t;
    int i=s.size()-1,j=t.size()-1;
    for(;i>=0 && j >=0;i--,j--)
    {
        if(s[i] != t[j])
        {
            cout<<i+j+2;
            return 0;
        }
    }

    cout<<i+j+2;

    return 0;
}
//

CF1005A

找1,长度为下一个 1 的位置减去当前 1 的位置

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};

const int N = 1005;

int a[N];
vector<int> len;

int main()
{
    ios::sync_with_stdio(0);

    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    
    for(int i=1;i<=n;i++) 
    {
        int suc = i;
        while(suc<n && a[suc] < a[suc+1]) suc++;
        len.push_back(suc - i + 1);        
        i = suc;
   }

    cout<<len.size()<<endl;
    for(int i=0;i<len.size();i++) cout<<len[i]<<' ';

    return 0;
}

//

CF1009B

贪心,将所有 1 插入到第一个 2 的前面

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 0;

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	string s,ans;
    cin>>s;
    
    int n = s.size(), cnt = 0;
    for(int i=0;i<n;i++)    
        if(s[i] == '1') cnt++;
        else ans += s[i];

    n = ans.size();
    int pos = n;
    for(int i=0;i<n;i++)
        if(ans[i] != '0')
        {
            pos = i;
            break;
        }

    ans.insert(pos,string(cnt,'1'));

    cout<<ans;

    return 0;
}
//

CF1009A

扫一遍数组,能买就买

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

const int N = 1005;
int a[N];
int b[N];

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=m;i++) cin>>b[i];
    
    int ans = 0;
    for(int i=1,j=1;i<=n&&j<=m;i++)
    {
        if(a[i] <= b[j]) j ++, ans ++;
    }

    cout<<ans;

    return 0;
}
//

CF1076A

找到第一个波峰,把它删掉

#include <bits/stdc++.h>
using namespace std;

const int N = 2*1e5+10;

int n;
char str[N];

int main()
{
    cin>>n>>str;
    
    for(int i=0;i<n;i++)
        if(i == n-1) 
        {
            str[i] = 0;
            puts(str);
            break;
        }
        else if(str[i] > str[i+1])
        {
            str[i] = 0;
            printf("%s%s\n",str,str+i+1);
            break;
        }
    return 0;
}

CF1092A

输出 $ \lfloor n / k \rfloor $ 个a, $ \lfloor n / k \rfloor $ 个b, $ \lfloor n / k \rfloor $ 个c ... 最后输出 $ \lfloor n / k \rfloor + n \mod k$ 个a

#include <bits/stdc++.h>
using namespace std;

int main()
{
   int t;
   cin>>t;
   
   while(t--)
   {
   	int n,k;
   	cin>>n>>k;
   	
       int times = n/k;
       
       string str;
       for(int i=0;i<k;i++)
           for(int j=1;j<=times;j++)
           {
               str += 'a' + i;
           }
       
       for(int i=1;i<=n - k * times;i++) str += 'a';
       
       cout<<str<<endl;
   }
   
   return 0;
} 

CF1099B

尽可能拼成正方形,枚举宽度,算长度

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    
    int minn = 0x3f3f3f3f;
    for(int i=1;i<=(n+i-1)/i;i++)
    {
        minn = min(minn,i+(n+i-1)/i);
    }
    
    cout<<minn<<endl;
}

CF1105A

排序,枚举t,计算距离,得出答案

#include <bits/stdc++.h>
using namespace std;

const int N = 1010;

int w[N];
int n;

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>w[i];
    
    sort(w+1,w+n+1);
    
    int pos,minn = 0x3f3f3f3f;
    for(int i=1;i<=1000;i++)
    {
        int dis = 0;
        for(int j=1;j<=n;j++)
            dis += max(abs(i-w[j])-1,0);
        if(dis < minn) minn = dis,pos = i;
    }
    
    cout<<pos<<' '<<minn<<endl;
    
    return 0;
}

CF1141B

破环成链,暴力扫一遍

#include <bits/stdc++.h>
using namespace std;

const int N = 400005;

int w[N];
int n;

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>w[i],w[i+n] = w[i];
    
    int suc = 0,maxx = 0;
    for(int i=1;i<=2*n;i++)
        if(w[i]) suc ++;
        else maxx = max(maxx,suc), suc = 0;
        
    cout<<maxx<<endl;
}

CF1304B

开个set,把所有串塞进去

枚举所有串,如果他的 reverse 在set里,就把它的reverse删掉

#include <bits/stdc++.h>
using namespace std;

const int N = 105;

string str[N];

vector<string> l,r;
string mid;

set<string> dirt;

int main()
{
    int n,m;
    cin>>n>>m;

    for(int i=1;i<=n;i++) cin>>str[i],dirt.insert(str[i]);

    for(int i=1;i<=n;i++)
    {
        string t = str[i];
        reverse(t.begin(),t.end());
        
        if(t == str[i]) mid = str[i]; 
        else if(dirt.find(t) != dirt.end())
        {
            l.push_back(t);
            r.push_back(str[i]);
            dirt.erase(t);
            dirt.erase(str[i]);
        } 
    }

    cout<<l.size() * m + r.size() * m + mid.size()<<endl; 

    for(int i=l.size()-1;i>=0;i--) cout<<l[i];
    cout<<mid;
    for(int i=0;i<r.size();i++) cout<<r[i];

    return 0;
}

CF1304A

如果 (y - x ) % (a + b) == 0,答案为 (y - x ) / (a + b)

否则为-1

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int t;
    cin>>t;

    while(t--)
    {
        int x,y,a,b;
        cin>>x>>y>>a>>b;
        
        if((y-x)%(a+b) == 0) cout<<(y-x)/(a+b);
        else cout<<-1;

        cout<<endl;
    }

    return 0;
}//

CF1313B

最高为 x+y-n , 最低为 x + y - 1

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	cin>>t;
	
	while(t--)
	{
		int n,x,y;
		cin >> n >> x >> y;
		
		int maxx = min(max(x + y + 1 - n , 1), n);
		int minn = min(x + y - 1, n);
		
		cout << maxx << ' ' << minn << endl;
	}
	
	return 0;
}
//

CF1313A

因为每种最多只能提供一份,所以最多只有 7 种情况,只需要判断这 7 种情况是否都可行就可以了

#include <bits/stdc++.h>
using namespace std;

const int N = 15;

int f[N][N][N];
int cost[10][3] = {{1,0,0},{0,1,0},{0,0,1},{1,0,1},{1,1,0},{0,1,1},{1,1,1}};

int main()
{
	ios::sync_with_stdio(0);
	int	t;
	cin>>t;
	
	while(t--)
	{
		memset(f,0,sizeof f);
		int a, b, c;
		cin >> a >> b >> c;
		
		for(int i=0;i<7;i++)
			for(int j=a;j>=cost[i][0];j--)
				for(int k=b;k>=cost[i][1];k--)
					for(int l=c;l>=cost[i][2];l--)
						f[j][k][l] = max(f[j][k][l],f[j-cost[i][0]][k-cost[i][1]][l-cost[i][2]] + 1);
		
		cout<<f[a][b][c]<<endl;				
	}	
	
	return 0;
}
//

CF1395A

细节题

如果\(r,g,b,w\) 中有三个以上为偶数,则为yes

如果\(r,g,b,w\) 中有两个为偶数,则为no

如果\(r,g,b\) 中有一个为0,则为no

其他都为yes

#include <bits/stdc++.h>
using namespace std;

long long n;  

int main()
{
    scanf("%lld",&n);

    while(n--)
    {
        long long r,g,b,w;
        scanf("%lld%lld%lld%lld",&r,&g,&b,&w);

        int cnt=0;
        if(r%2==0) cnt++;
        if(g%2==0) cnt++;
        if(b%2==0) cnt++;
        if(w%2==0) cnt++;

        if(cnt>=3) puts("Yes");
        if(!r || !g || !b) puts("No");
        else if(cnt == 2) puts("No");
        else puts("Yes");
    }

    return 0;
}

CF1392D

唯一的不符合条件的情况是有连续的 3 个相同的字符(A打B,B打C,C打D)

破环成链,统计连续字符的个数,每一段连续对答案的贡献为 长度 / 3

细节:对于所有字符都相同的要特判,答案为\((n + 2)/3\)

#include <bits/stdc++.h>
using namespace std;

const int N = 4e5 + 10;

char s[N];
int n;

bool same()
{
	for(int i=2; i<=n; i++)
		if(s[i] != s[1])
			return 0;
	return 1;
}

void solve()
{
	cin>>n>>s+1;

	if(same())
	{
		cout << (n - 1) / 3 + 1<<endl;
		return ;
	}

	int pos = 0;
	for(int i=1; i<=n; i++) // find the legal braek point
		if(s[i] != s[n])
		{
			pos = i - 1;
			break;
		}

	for(int i=1; i<=n; i++) s[i+n] = s[i];
	for(int i=1; i<=n; i++) s[i] = s[i + pos];

	int ans = 0,suc = 0;
	for(int i=1; i<=n; i++)
	{
		if(s[i] != s[i - 1]) ans += suc / 3, suc = 0;
		suc ++;
	}

	ans += suc / 3;
	cout<<ans<<endl;
}

int main()
{
	int t;
	cin>>t;

	while(t--)
	{
		solve();
	}

	return 0;
}
posted @ 2021-10-07 22:24  BorisDimitri  阅读(38)  评论(1编辑  收藏  举报