CF1461

CF1461

String Generation

\(k\) 是没有用的 直接按照 \(abc\) 的顺序输出即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define mid (l+r>>1)
#define ls p<<1
#define rs p<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define getchar() cin.get()
#define print(x) cout<<#x<<'='<<x<<endl
#define int long long
const int N = 1e6 + 5;
const int inf = 0x3f3f3f3f;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , k , tot , ans = inf;

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		n = read() , k = read();
		for ( int i = 1 ; i <= n ; i ++ )
		{
			if ( i % 3 == 1 ) cout << 'a';
			if ( i % 3 == 2 ) cout << 'b';
			if ( i % 3 == 0 ) cout << 'c';
		}
		cout << endl;
	}
	return 0;
}

Find the Spruce

很有意思的题 我们设 \(f[i][j][k]\)\((i,j)\) 节点 大小为 \(k\) 的可行性

那么 \(f[i][j][k]\) 可行当且仅当它下一行的三个节点都可以做出 \(k-1\) 大小的树

那么 \(O(nmk)\) 枚举即可 其中 \(k\) 可以取 \(max(n,m)/2+1\) 不然会炸空间

最后只需要累加一下即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define mid (l+r>>1)
#define ls p<<1
#define rs p<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define getchar() cin.get()
#define print(x) cout<<#x<<'='<<x<<endl
const int N = 500 + 5;
const int inf = 0x3f3f3f3f;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , m , k , tot , f[N][N][255] , ans;

char mp[N][N];

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		ans = 0;
		memset ( f , 0 , sizeof f );
		n = read() , m = read();
		for ( int i = 1 ; i <= n ; i ++ )
			for ( int j = 1 ; j <= m ; j ++ )
				cin >> mp[i][j] , f[i][j][1] = ( mp[i][j] == '*' );
		for ( int i = n - 1 ; i ; i -- )
			for ( int j = 1 ; j <= m ; j ++ )
				for ( int k = 2 ; k <= max ( n , m ) / 2 + 1 ; k ++ )
					if ( f[i+1][j-1][k-1] && f[i+1][j][k-1] && f[i+1][j+1][k-1] && mp[i][j] == '*' ) f[i][j][k] = 1;
		for ( int k = 1 ; k <= max ( n , m ) / 2 + 1 ; k ++ )
			for ( int i = 1 ; i <= n ; i ++ )
				for ( int j = 1 ; j <= m ; j ++ )
					ans += f[i][j][k];
		cout << ans << endl;
	}
	return 0;
}

Random Events

可以从后往前找到第一个 \(a[i]\neq i\) 的位置 \(pos\) 所有在 \(pos\) 后面的操作才会影响 否则不影响

只要有一个达成目标即可 那么我们算出全不选的概率再用 \(1\) 减掉

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define mid (l+r>>1)
#define ls p<<1
#define rs p<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define getchar() cin.get()
#define print(x) cout<<#x<<'='<<x<<endl
const int N = 500 + 5;
const int inf = 0x3f3f3f3f;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , m , k , tot , f[N][N][255] , ans , a[N];
double gl , res;

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		res = 1.0;
		n = read() , m = read();
		int pos = 0;
		for ( int i = 1 ; i <= n ; i ++ ) a[i] = read();
		for ( int i = n ; i ; i -- ) if ( i != a[i] ) { pos = i; break; }
		for ( int i = 1 ; i <= m ; i ++ )
		{
			int x = read(); cin >> gl;
			if ( x >= pos ) res *= ( 1.0 - gl );
		}
		if ( !pos ) { cout << "1.000000" << endl; continue; }
		cout << fixed << setprecision(6) << 1.0 - res << endl;
	}
	return 0;
}

Divide and Summarize

暴力可过 破防了

一共只会有 \(nlogn\) 个区间 那么直接暴力用 \(map\) 标记即可

要开 \(long\ long\)

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define mid (l+r>>1)
#define ls p<<1
#define rs p<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define getchar() cin.get()
#define print(x) cout<<#x<<'='<<x<<endl
#define int long long
const int N = 1e5 + 5;
const int M = 1e6 + 5;
const int inf = 0x3f3f3f3f;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , q , a[N] , sum[N];
map<int,int> mp;

void solve ( int l , int r )
{
	mp[sum[r]-sum[l-1]] = 1;
	if ( l == r ) return;
	int pos = upper_bound ( a + l , a + r + 1 , ( a[l] + a[r] ) / 2 ) - a - 1;
	if ( pos >= r ) return;
	solve ( l , pos ) , solve ( pos + 1 , r );
}

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		mp.clear();
		n = read() , q = read();
		for ( int i = 1 ; i <= n ; i ++ ) a[i] = read();
		sort ( a + 1 , a + n + 1 );
		for ( int i = 1 ; i <= n ; i ++ ) sum[i] = sum[i-1] + a[i];
		solve ( 1 , n );
		while ( q -- ) cout << ( mp[read()] ? "Yes" : "No" ) << endl;
	}
	return 0;
}

Water Level

分讨题()

我们对 \(x\)\(y\) 的大小关系进行考虑

  • \(x=y\) 只要加一次水或者喝一次水在区间内就是合法的

  • \(x>y\) 那么相当于是水量一直在减少 那么用除法算一下还能喝多少天(注意特判第一次加水溢出的情况)

  • \(x<y\) 我们不担心水不够 而是担心会不会溢出 那么我们每一次都减到 \(\ge l\) 的第一个位置 并让目标天数减去这些天

    如果 \(\le 0\) 那么直接输出 \(Yes\) 否则更新水量并加上 \(y\)

    一个优化:我们记录 \(k \bmod x\) 的值是否被访问过 如果访问过 那么一定是可以通过一些循环来实现无限次的控制水量 输出 \(Yes\)

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define mid (l+r>>1)
#define ls p<<1
#define rs p<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define getchar() cin.get()
#define print(x) cout<<#x<<'='<<x<<endl
#define int __int128
const int N = 1e6 + 5;
const int mod = 1e9 + 7;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int k , l , r , t , x , y , vis[N];

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	k = read() , l = read() , r = read() , t = read() , x = read() , y = read();
	if ( x == y ) cout << ( ( l <= k - x || k + x <= r ) ? "Yes" : "No" ) << endl;
	else if ( x > y )
	{
		int res = 0;
		if ( k + y > r ) k -= x , ++ res;//溢出 不能加水
		if ( k < l ) return cout << "No" << endl , 0;
		res += ( k - l ) / ( x - y );
		cout << ( res >= t ? "Yes" : "No" ) << endl;
	}
	else 
	{
		while ( t > 0 )
		{
			if ( vis[k%x] ) return cout << "Yes" << endl , 0;
			int rem = min ( t , ( k - l ) / x );
			t -= rem;
			if ( t <= 0 ) return cout << "Yes" << endl , 0;
			k -= rem * x , vis[k%x] = 1 , k += y;
			if ( k < l || k > r ) return cout << "No" << endl , 0;
		}
	}
	return 0;
}

Mathematical Expression

随的一场 \(CF\) 竟然出现了模拟赛原题?

首先分讨

  1. 三种全有 显然减号是没用的 相当于只有加和乘 归入下面的情况中
  2. 只有两种
    • 加和乘 这是我们讨论的重点 放在下面讨论
    • 减和加 一定加就完事了
    • 减和乘 一定是找到从前往后第一个 \(0\) 这个数的前面为减号 其余符号均为乘号 对于这个数在第一位的情况特判一下即可
  3. 只有一种 直接输出即可

下面讨论加乘的情况

\(upd:\)\(1h\) 题解后放弃 真 \(tm\) 做不了 下面给出除了加乘的代码

#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define inl inline
#define eb emplace_back
#define endl '\n'
#define print(x) cerr<<#x<<'='<<x<<endl
#define getchar() cin.get()
const int N = 1e5 + 5;
int read()
{
	int x = 0 , f = 1;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , m , a[N] , vis[3] , ans , t[N];//+-*
string s , res;

namespace sub1
{
	void main()
	{
		
	}
}

namespace sub2
{
	void main ()
	{
		cout << a[1];
		for ( int i = 2 ; i <= n ; i ++ )
			cout << '+' << a[i];
	}
}

namespace sub3
{
	void main ()
	{
		int hav = 0;
		cout << a[1];
		for ( int i = 2 ; i <= n ; i ++ )
		{
			if ( !a[i] && !hav ) cout << '-' , hav = 1;
			else cout << '*';
			cout << a[i];
		}
	}
}

namespace sub4
{
	void main ()
	{
		cout << a[1];
		for ( int i = 2 ; i <= n ; i ++ )
		{
			if ( vis[0] ) cout << '+';
			else if ( vis[1] ) cout << '-';
			else cout << '*';
			cout << a[i];
		}
		cout << endl;
	}
}

/*
5
1 2 3 0 5
+*
*/

signed main ()
{
	// freopen ( "max.in" , "r" , stdin );
	// freopen ( "max.out" , "w" , stdout );
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	n = read();
	for ( int i = 1 ; i <= n ; i ++ ) a[i] = read();
	cin >> s;
	for ( int i = 0 ; i < s.size() ; i ++ ) 
	{
		if ( s[i] == '+' ) vis[0] = 1;
		else if ( s[i] == '-' ) vis[1] = 1;
		else vis[2] = 1;
	}
	int judge = vis[0] + vis[1] + vis[2];
	if ( judge == 3 || vis[0] && vis[2] ) sub1::main();
	else if ( vis[0] && vis[1] ) sub2::main();//+-
	else if ( vis[1] && vis[2] ) sub3::main();//*-
	else sub4::main();//only 1
	return 0;
}

posted @ 2023-11-02 16:37  Echo_Long  阅读(7)  评论(0编辑  收藏  举报