2021绍兴市联赛游记

🎈A - Chess Game

题意

给两个点坐标,A棋子坐标,B棋子坐标,先手可以上下左右走一步A点,后手可以封除AB两个棋子坐标外的任意一个坐标,求先手能不能走到B

思路

两步之内必能走到,三步需要不在同行or同列,签到

🎈B - Bracket Matching

题意


这个序列甚至比Lecxcy还要古老,所以一些括号已经模糊了。我们用星号代替它们。

现在Lecxcy只知道他拥有的序列是一个有效的括号序列,每个模糊的括号只能是左括号、右括号和空括号中的一个。

莱克西想弄清楚有多少序列可能是原始序列。

Null是有效的括号序列。

如果X和Y是有效的括号序列,那么XY也是有效的括号序列。

如果X是一个有效的括号序列,那么(X)也是一个有效的括号序列

比如***可以变成(*) *()()* ***

思路

比赛的时候想过于复杂,因为长度3k,所以二维dp,i表示这个一层状态,j表示左括号的数量

状态转移方程三种状态

当s[i]==* ,dp[i][j]=(dp[i-1][j-1]+dp[i-1][j]+dp[i-1][j+1])%mod

当s[i]==(,dp[i][j]=dp[i-1][j-1]

当s[i]==),dp[i][j]=dp[i-1][j+1]

AC代码

#include<bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define ll long long
#define mod 1000000007
#define inf 0x7f
#define ull unsigned long long
using namespace std;
const int N=3e3+10;
char s[N];
ll dp[N][N];
int main() {
	scanf("%s",s);
	int n=strlen(s);
	dp[0][0]=1;
	for(int i=1;i<=n;i++){
		if(s[i-1]=='*'){
			for(int j=0;j<=n;j++) dp[i][j]=(dp[i-1][j-1]+dp[i-1][j]+dp[i-1][j+1])%mod;
		}
		else if(s[i-1]=='('){
			for(int j=0;j<=n;j++) dp[i][j]=dp[i-1][j-1];
		}
		else{
			for(int j=0;j<=n;j++) dp[i][j]=dp[i-1][j+1];
		}
	}
	printf("%lld\n",dp[n][0]);
	return 0;
}

🎈C - Compare(Easy Version)

题意

判断a+b是否大于c,签到

🎈E - Compare(Hard Version)

题意

√a+√b 是否大于 √c

思路

只要判断(c-a-b)2是否大于4 * a * b,再特判一下c-a-b是否小于0即可,签到

🎈F - Lecxcy and SakuKumo

题意

问给出一个n,1/n!=1/a-1/b 这样的个数有几个,n小于1e7

思路

比赛时候没推出来,QAQ

AC代码

#include<bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define ll long long
#define mod 1000000007
#define inf 0x7f
#define ull unsigned long long
using namespace std;
const int N=1e7;
int prime[N/10];
int vis[N];
int m=0;
ll ksm(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1){
            ans*=a;ans%=mod;
        }
        a*=a;a%=mod;
        b>>=1;
    }
    return ans;
}
void init(){
	for(int i=2;i<N;i++){
		if(!vis[i])prime[++m]=i;
		for(int j=1;j<=m&&prime[j]*i<N;j++){
			vis[prime[j]*i]=1;
			if(i%prime[j]==0)break;
		}
	}
}
int main(){
	int T;
	init();
	scanf("%d",&T);
	while(T--){
		int n;
		scanf("%d",&n);
		ll ans=1;
		for(int i=1;i<=m && prime[i]<=n;i++){
			ll tmp=n,e=0;
			while(tmp){
                              e+=(tmp/=prime[i]);
			}
			ans=ans*((ll)2*e+1)%mod;
		}
		ans=((ans-1+mod)%mod*ksm((ll)2,mod-2))%mod;
		printf("%lld\n",ans);
	}
	return 0;
}

整除分块的补充说明

1~n之间有多少2的个数
比如 12345678910有8个2(2,4,6,8,10)
ll tmp=n,e=0;
while(tmp){
    e+=(tmp/=2);
}

🎈G - Wythoff's Game Pro

题意

有三堆石头,两个人拿石头,可以每堆都拿相同数量石头,也可以一堆拿一些石头

思路

尼姆博弈,特判全是1的情况也不需要了,直接a^ b ^c即可

🎈H - Twinkle Twinkle Little Star

题意

给n个点,m条线的无向图。给q个pos,len,color分表表示点坐标扩展出去len长度,染成color数字,会覆盖

思路

比赛的时候这题数据没看清,nmq都是1e5,len居然是10……,只要倒着染,标记每个点可染色长度,如果大于等于就return,没标记和标记短的就继续。

AC代码

#include<bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define ll long long
#define mod 1000000007
#define inf 0x7f
#define ull unsigned long long
using namespace std;
const int N=2e5+10;
int n, m;
int head[N],to[N],ne[N],tot;
int ans[N],dist[N];
int v[N],d[N],c[N];
void add(int u, int v){
    to[tot] = v;
    ne[tot] = head[u];
    head[u] = tot++;
}
void dfs(int fa,int u, int color, int deep){
    if(!ans[u]) ans[u] = color;
    if(deep == 0 || dist[u] >= deep) return;
    dist[u] = deep;
    for(int i=head[u];~i;i=ne[i]){
	int v=to[i];if(fa==v)continue;
	dfs(u,v,color,deep-1);
    }
}
int main(){
	scanf("%d%d",&n,&m);
	mem(head,-1);
	for(int i=1;i<=m;++i){
	    int u,v;scanf("%d%d",&u,&v);
            add(u,v);
	    add(v,u);
	}
	int q;scanf("%d",&q);
	for(int i=1;i<=q;++i){
	    scanf("%d%d%d",&v[i],&d[i],&c[i]);
	}
	for(int i=q;i>=1;--i){
	    dfs(0,v[i], c[i], d[i]);
	}
	for(int i=1;i<=n;++i){
	    printf("%d\n",ans[i]);
	}
	return 0;
}

🎈I - Meet in Another World, Enjoy Delicious

题意

这题面有毒,小明最近听说肯德基和他最喜欢的游戏有关,于是去排队买了N天的根欣盒(N是个奇数)。活动异常火爆,但小明所在的城市只有一家肯德基。他在i天成功购买Genshin Box的概率是p[i],他能成功购买Genshin Box超过N/2天的概率是多少。比赛翻了好久这题

思路

数据2999,直接二维dp,i表示胜利天数,j表示失败天数

状态转移方程就是dp[i][j]=dp[i-1][j] * a[i+j]+dp[i][j-1] * (1-a[i+j]);

初始化,然后累加i大于j的dp[i][j]即可

AC代码

#include<bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define ll long long
#define mod 1000000007
#define inf 0x7f
#define ull unsigned long long
using namespace std;
const int N=3e3+10;
int n, m;
double a[N];
double dp[N][N];
int main(){
	scanf("%d",&n);
	mem(dp,0);
	dp[0][0]=1;
	for(int i=1;i<=n;i++){
            scanf("%lf",&a[i]);
	}
	for(int i=1;i<=n;i++){
            dp[i][0]=dp[i-1][0]*a[i];
            dp[0][i]=dp[0][i-1]*(1-a[i]);
	}
	for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                dp[i][j]=dp[i-1][j]*a[i+j]+dp[i][j-1]*(1-a[i+j]);
            }
	}
	double ans=0;
	for(int i=n/2+1;i<=n;i++){
            ans+=dp[i][n-i];
	}
	printf("%.3f\n",ans);
	return 0;
}

翻译队友跑路,队友打阴阳师活动,题目翻错,数据看大

难得线下赛,就当春游了,又吃绍职的一楼饭,👍,顺便溜达了一圈银泰

posted @ 2021-04-12 16:33  ouluy  阅读(104)  评论(3编辑  收藏  举报