首页 > 其他分享 >M-SOLUTIONS Programming Contest

M-SOLUTIONS Programming Contest

时间:2023-09-27 19:24:53浏览次数:39  
标签:return Contest int inv Programming long SOLUTIONS include MOD

A - Sum of Interior Angles

答案为 \(180(n-2)\)。


#include<iostream>
#include<cstdio>
using namespace std;
int n;
int main()
{
	scanf("%d",&n);
	printf("%d",180*(n-2));
	return 0;
}

B - Sumo

判断一下 x 的个数是否小于等于 \(7\)。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=20;
int n;
char s[N];
int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	int cnt=0;
	for(int i=1;i<=n;i++)
		if(s[i]=='x') cnt++;
	if(15-cnt>=8) printf("YES");
	else printf("NO");
	return 0;
}

C - Best-of-(2n-1)

令 \(a=\frac{A}{100}\),\(b=\frac{B}{100}\)。

先不考虑 \(c\),最后再将 \(c\) 加入。考虑确定了 \(A,B\) 的顺序以后,如果在第 \(n\) 局停止,我们有 \(n\) 个位置可以插入 \(c\)。则插入的 \(c\) 的期望个数为:

\[\sum\limits_{i=0}^{n} C_{n}^{i}\cdot i\sum\limits_{k=0}^{\infty}(1-a-b)^k=\frac{1}{a+b} \]

考虑计算没有平局的情况。枚举在第 \(i\) 局停止,则概率为

\[a^{n}b^{i-n}C_{i-1}^{n-1}+b^{n}a^{i-n}C_{i-1}^{n-1} \]

直接计算即可。


#include<iostream>
#include<cstdio>
using namespace std;
const int N=200005;
const int MOD=1000000007;
int n;
int A,B,c;
long long ksm(long long a,long long b)
{
	long long res=1;
	while(b)
	{
		if(b&1) res=res*a%MOD;
		a=a*a%MOD,b>>=1;
	}
	return res;
}
long long fac[N],inv[N];
void init(int n=200000)
{
	fac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=fac[i-1]*i%MOD;
	inv[n]=ksm(fac[n],MOD-2);
	for(int i=n;i>=1;i--)
		inv[i-1]=inv[i]*i%MOD;
	return;
}
long long C(int n,int m)
{
	if(m>n) return 0;
	else return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}
int main()
{
	init();
	scanf("%d",&n);
	scanf("%d%d%d",&A,&B,&c);
	int a=1LL*A*ksm(A+B,MOD-2)%MOD,b=1LL*B*ksm(A+B,MOD-2)%MOD;
	long long ans=0;
	for(int i=n;i<n*2;i++)
	{
		long long res=(ksm(a,n)*ksm(b,i-n)%MOD*C(i-1,n-1)%MOD+ksm(b,n)*ksm(a,i-n)%MOD*C(i-1,n-1)%MOD)%MOD*i%MOD;
		ans=(ans+res)%MOD;
	}
	ans=ans*100%MOD*ksm(A+B,MOD-2)%MOD;
	printf("%lld",ans);
	return 0;
}

D - Maximum Sum of Minimum

考虑贪心,每次贪心将最小的给叶子节点,这样子的答案即为前 \(n-1\) 小的元素之和,可以证明这是最优的。


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N=10005;
int n;
int c[N];
int d[N],tot;
vector<int>G[N];
void dfs(int u,int father)
{
	for(int v:G[u])
	{
		if(v==father) continue;
		dfs(v,u);
	}
	d[u]=c[++tot];
	return;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(int i=1;i<=n;i++)
		scanf("%d",&c[i]);
	sort(c+1,c+n+1);
	dfs(1,0);
	int sum=0;
	for(int i=1;i<n;i++)
		sum+=c[i];
	printf("%d\n",sum);
	for(int i=1;i<=n;i++)
		printf("%d ",d[i]);
	return 0;
}

E - Product of Arithmetic Progression

考虑 \(d=1\) 时用两个阶乘除一下就好了。\(d> 1\) 的情况将每一项都除以 \(d\),问题就变成了 \(d=1\) 的情况。


#include<iostream>
#include<cstdio>
using namespace std;
const int MOD=1000003;
int Q;
long long ksm(long long a,long long b)
{
	long long res=1;
	while(b)
	{
		if(b&1) res=res*a%MOD;
		a=a*a%MOD,b>>=1;
	}
	return res;
}
long long fac[MOD],inv[MOD];
void init(int n=1000002)
{
	fac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=fac[i-1]*i%MOD;
	inv[n]=ksm(fac[n],MOD-2);
	for(int i=n;i>=1;i--)
		inv[i-1]=inv[i]*i%MOD;
	return;
}
void solve()
{
	int x,d,n;
	scanf("%d%d%d",&x,&d,&n);
	if(d==0)
	{
		printf("%lld\n",ksm(x,n));
		return;
	}
	x=x*ksm(d,MOD-2)%MOD;
	if(x==0||x+n-1>=MOD)
	{
		printf("0\n");
		return;
	}
	long long ans=fac[x+n-1]*inv[x-1]%MOD;
	printf("%lld\n",ans*ksm(d,n)%MOD);
	return;
}
int main()
{
	init();
	scanf("%d",&Q);
	while(Q--)
		solve();
	return 0;
}

F - Random Tournament

考虑 DP,令 \(fl_{l,r}\) 表示 \(l\) 能否打败 \([l,r]\),\(fr_{l,r}\) 表示 \(r\) 能否打败 \([l,r]\)。

以 \(fl\) 的转移为例,枚举 \(l\) 最后打败的人 \(k\)。合法的条件即为存在一个 \(u\) 使得 \(i\) 能打败 \([i+1,u]\) 且 \(k\) 能打败 \([u+1,j]\),可以发现 \(u\) 有用的只有 \(i+1\)。因为如果 \(u\) 能够打败 \(k\),这种情况应该在 \(k=u\) 时已经计算过了,否则 \(k\) 显然是可以再往前拓展一格的。这种情况下 \(i\) 想要获胜的条件即为 \(i\) 能够打败 \(k\) 且 \(fr_{i+1,k}\) 和 \(fl_{k,r}\) 均为真。\(fr\) 同理。

这个可以用 bitset 优化,或者说跟我一样大力卡常就可以通过此题。


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N=2005;
int n;
int a[N][N];
bool fl[N][N],fr[N][N];
vector<int>pos[N];
int main()
{
	freopen("114.in","r",stdin);
	freopen("114.out","w",stdout);
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
		for(int j=1;j<=i-1;j++)
			scanf("%1d",&a[i][j]),a[j][i]=a[i][j]^1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(a[i][j]) pos[i].push_back(j);
	for(int i=1;i<=n;i++)
		fl[i][i]=fr[i][i]=true;
	for(int len=2;len<=n;len++)
		for(int i=1;i+len-1<=n;i++)
		{
			int j=i+len-1;
			int l=lower_bound(pos[i].begin(),pos[i].end(),i+1)-pos[i].begin(),r=upper_bound(pos[i].begin(),pos[i].end(),j)-pos[i].begin()-1;
			for(int p=l;p<=r;p++)
			{
				int k=pos[i][p];
				fl[i][j]|=fr[i+1][k]&fl[k][j];
				if(fl[i][j]) break;
			}
			l=lower_bound(pos[j].begin(),pos[j].end(),i)-pos[j].begin(),r=upper_bound(pos[j].begin(),pos[j].end(),j-1)-pos[j].begin()-1;
			for(int p=l;p<=r;p++)
			{
				int k=pos[j][p];
				fr[i][j]|=fr[i][k]&fl[k][j-1];
				if(fr[i][j]) break;
			}
		}
	int ans=0;
	for(int i=1;i<=n;i++)
		if(fr[1][i]&&fl[i][n]) ans++;
	printf("%d",ans);
	return 0;
}

标签:return,Contest,int,inv,Programming,long,SOLUTIONS,include,MOD
From: https://www.cnblogs.com/zhou-jk/p/17734061.html

相关文章

  • Keyence Programming Contest 2020
    A-Painting每次取\(H,W\)中较大者涂就是了,输出\(\lceil\frac{n}{\max(H,W)}\rceil\)。代码:#include<iostream>#include<cstdio>usingnamespacestd;inth,w,n;intmain(){ scanf("%d%d%d",&h,&w,&n); if(h<w)swap(h,w); ......
  • NOMURA Programming Competition 2020
    A-StudyScheduling先算出总时间,然后在减去\(K\)就好了。代码:#include<iostream>#include<cstdio>usingnamespacestd;inth1,m1,h2,m2,k;intmain(){ scanf("%d%d%d%d%d",&h1,&m1,&h2,&m2,&k); intansh=h2-h1,ansm=m2-m1; if......
  • NIKKEI Programming Contest 2019-2
    A-SumofTwoIntegers分奇偶讨论一下就好了,答案为\(\lfloor\frac{n-1}\{2\}\rfloor\)。#include<iostream>#include<cstdio>usingnamespacestd;intn;intmain(){ scanf("%d",&n); printf("%d",(n-1)/2); return0;}B-......
  • Tenka1 Programmer Contest 2019
    C-Stones枚举分界点爆算即可。#include<iostream>#include<cstdio>usingnamespacestd;constintN=200005;intn;chars[N];intsum[N][2];intmain(){ scanf("%d",&n); scanf("%s",s+1); sum[0][0]=sum[0][1]=0; for(inti=1;i......
  • Social Infrastructure Information Systems Division, Hitachi Programming Contest
    A-HitachiString满足条件的串即为串长为偶数且相邻两个均为为hi,直接判断即可。代码:#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintN=15;intn;chars[N];intmain(){ scanf("%s",s+1); n=strlen(s+1); if(n&1) ......
  • Yahoo Programming Contest 2019
    A-Anti-Adjacency合法的条件即为\(k\leq\lceil\frac{n}{2}\rceil\)。#include<iostream>#include<cstdio>usingnamespacestd;intn,k;intmain(){ scanf("%d%d",&n,&k); if((n+1)/2>=k)printf("YES"); elsepri......
  • Tokio Marine & Nichido Fire Insurance Programming Contest 2020
    A-Nickname直接输出前三个字符。代码:#include<iostream>#include<cstdio>usingnamespacestd;constintN=25;chars[N];intmain(){ scanf("%s",s+1); printf("%c%c%c",s[1],s[2],s[3]); return0;}B-Tag如果\(v\leqw\),则显然不......
  • AtCoder Grand Contest 025
    A-DigitsSum按题意模拟即可。#include<iostream>#include<cstdio>usingnamespacestd;constintINF=1061109567;intn;intcalc(intx){intres=0;while(x)res+=x%10,x/=10;returnres;}intmain(){scanf("%d",&......
  • AtCoder Grand Contest 026
    A-ColorfulSlimes2可以发现,对于连续的一段长度为\(m\)的相同的字符,我们可以花费\(\lfloor\frac{m}{2}\rfloor\)的代价将它改为符合要求的。#include<iostream>#include<cstdio>usingnamespacestd;constintN=105;intn;inta[N];intmain(){scanf("%d"......
  • AtCoder Grand Contest 022
    A-DiverseWord如果至少有一个字符没有出现过,只要在原字符串后面加入一个没有出现过的字符中最小的那个字符就好了。如果所有字符都出现过,找到一个尽量靠后的位置\(i\in[1,n)\),使得\(s_i\lts_{i+1}\),最优字符串将\(s_i\)换成\([i+1,n]\)里面比\(s_i\)大的最小的那个......