THUPC 2024初赛 组队VP 2024.12.7

组队的思路不会写太清楚,这个只供日后队内需要进行查看

C.前缀和

题面:

小兰喜欢随机数,TA首先选定了一个实数 \(0 < p < 1\),然后生成了 \(n\) 个随机数 \(x_1, \ldots, x_n\),每个数是独立按照如下方式生成的:

  • \(x_i\)\(p\) 的概率是 1,有 \((1-p)p\) 的概率是 2,有 \((1-p)^2p\) 的概率是 3,以此类推。

生成完这些随机数之后,小艾对这个数列求了前缀和,得到了数列 \(y_1, \ldots, y_n\)

给定 \(1 \leq l \leq r \leq n\),小兰想知道,期望有多少 \(y_i\) 落在 \([l, r]\) 内?
输入:

从标准输入读入数据。

一行输入四个数 \(n, p, l, r\)。保证 \(1 \leq l \leq r \leq n \leq 10^9\)\(p\) 的位数不超过 6。
输出:
输出到标准输出。
你需要保证答案的绝对或相对误差不超过 \(10^{-6}\)
样例:
3 0.5 1 2
————————
1.000000
思路:队友写的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
double a[1000050]={0};
double p;
int main(){
	int n,l,r;
	scanf("%d %lf %d %d",&n,&p,&l,&r);
	printf("%.7lf",(r-l+1)*p*1.0);
	
	return 0;
}

E.转化

题面:
小E有 \(n\) 种颜色的球,其中第 \(i\) 种有 \(a_i\) 个。有两类工具,第一类可以把一个指定颜色的球变成一个任意颜色的球;第二类可以把一个指定颜色的球变成两个这种颜色的球。一个变化之后的球也可以通过工具产生新的变化。关于第 \(i\) 种颜色的第一类工具有 \(b_i\) 个,第二类工具有 \(c_i\) 个。小E 想知道,如果每一个工具最多只能使用一次,那么对于每种颜色 \(i\),第 \(i\) 种颜色的球最后最多能有多少个。以及,小E 最后最多能有多少个球。
输入:
第一行包含一个正整数 \(n\)

第二行包含 \(n\) 个整数,其中第 \(i\) 个表示 \(a_i\)

第三行包含 \(n\) 个整数,其中第 \(i\) 个表示 \(b_i\)

第四行包含 \(n\) 个整数,其中第 \(i\) 个表示 \(c_i\)
输出:
第一行包含 \(n\) 个整数,其中第 \(i\) 个表示如果每个工具最多使用一次,那么小 E 最后第 \(i\) 种颜色的球最多有多少个。

第二行包含一个整数,表示如果每个工具最多使用一次,那么小 E 最后最多能有多少个球。
样例:
1:
2
1 2
1 2
1 0
————
4 3
4
思路:对于第一个输出分别可记录可转化的数量ans,需要一个球才能转化的数量cnt,然后对于每个球减去其贡献然后再考虑这两个贡献
对于第二个输出要求,统计有球且可转化的,需要一个球可以转化而且可以转化出去一个的,然后最后计算需要一个球但是不可以转化的,然后数学关系写出即可。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
//#include<bits/stdc++.h>
#include <unordered_map>
#define ll                               long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod =2;
//const ll p=rnd()%mod;
const ll maxn=5e5+15;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
struct s
{
	ll x;
	ll y;
	ll z;
}p[360000];
ll d[360000];
ll ans=0;
ll cnt=0;
int main()
{
	fio();
	ll n;
	cin>>n;
	for(ll i=1;i<=n;i++)cin>>p[i].x;
	for(ll i=1;i<=n;i++)cin>>p[i].y;
	for(ll i=1;i<=n;i++)cin>>p[i].z;
	ll pd=0;
	for(ll i=1;i<=n;i++)
	{
		if(p[i].x>0&&p[i].y>0)
		{
			ans+=min(p[i].y,p[i].x+p[i].z);//可转换
		}
		else if(p[i].x==0&&p[i].y==0)continue;
		else if(p[i].y>0&&p[i].x==0)
		{
			cnt=cnt-1+min(p[i].y,p[i].z+1);
		}
	}
	//cout<<ans<<endl;
	for(ll i=1;i<=n;i++)
	{
		if(p[i].x>0&&p[i].y>0)
		{
			if(ans>0)
			cout<<ans-min(p[i].y,p[i].x+p[i].z)+p[i].x+p[i].z+cnt<<" ";
			else cout<<p[i].x<<" ";
		}
		else if(p[i].x==0&&p[i].y>0)
		{
			if(ans>0)
			{
				if(p[i].y>=p[i].z+1)
     			cout<<ans+cnt<<" ";
				else 
				cout<<ans+cnt+p[i].z+1-p[i].y<<" ";
			}
			else cout<<0<<" ";
		}
		else if(p[i].x==0&&p[i].y==0)
		{
			if(ans>0)
			cout<<ans+cnt+p[i].z<<" ";
			else 
			cout<<ans<<" ";
		}
		else if(p[i].x>0&&p[i].y==0)
		{
			if(ans>0)
			cout<<ans+cnt+p[i].x+p[i].z<<" ";
			else cout<<p[i].x+p[i].z<<" ";
		}
	}
	cout<<endl;
	ll cf=0;
	ll cnt=0;
	ll u=0;
	priority_queue<ll>q;
	for(ll i=1;i<=n;i++)
	{
		if(p[i].x>0)
		{
			cf+=p[i].x+p[i].z;
			if(p[i].y>0)
			{
				cnt+=min(p[i].y,p[i].x+p[i].z);
			}
		}
	}
	for(ll i=1;i<=n;i++)
	{
		if(p[i].x==0&&p[i].z==0)
		continue;
		else if(p[i].x==0&&p[i].y>0)
		{
			if(cnt>0)
			{
				cf=cf-1+p[i].z+1;
				cnt-=1;
				cnt+=min(p[i].y,p[i].z+1);
			}
		}
		else if(p[i].x==0&&p[i].y==0)
		{
			if(p[i].z==0)continue;
			else q.push(p[i].z);
		}
	}
	while(!q.empty())
	{
		if(cnt>0)
		{
			cnt--;
			cf+=q.top();
		}
		q.pop();
	}
	cout<<cf<<endl;
}

K.三步棋

题面:

K 家里有一条不成文的规矩。如果家里只有 K 和 H 两个人,那么两个人会通过一种叫作“三步棋”的游戏来决定谁做饭。三步棋的规则与五子棋有一些相似之处。众所周知,五子棋是一种先连出五枚己方棋子者获胜的游戏。与五子棋相同的是,三步棋中双方也轮流在网格状的棋盘上摆放棋子,并根据是否连成指定的图案决定胜负。与五子棋不同的是:

  1. 三步棋不区分双方的棋子,即可以认为双方执同色棋子进行游戏;
  2. 在判定时,指定的图案不能旋转;
  3. 如果连成指定的图案时,棋盘上的棋子数量恰好为 $3$ 的倍数,则连成指定的图案的一方获胜,否则判定该方负(即对方获胜)。

例如,如果指定的图案为

.o
oo

且当前盘面为

o..o.
o.o..
oo...
o.o..
o..o.

时,认为没有连成给定的折线形图案,其中 o 表示棋子,. 表示空格;但若接下来在第二行第二列放一枚棋子,则连成了给定的图案,对应的棋子使用 @ 表示:

o..o.
o@o..
@@...
o.o..
o..o.

此时盘面上恰有 $11$ 枚棋子,而 $11$ 不是 $3$ 的倍数,所以判定放这枚棋子的玩家,也即先手输掉本局。

在 K 家,为了节约时间,通常使用 $5\times 5$ 的初始为空的棋盘进行三步棋。同时,每次也只会随机选择一个由不超过 $4$ 枚棋子组成的四连通图案。显然三步棋不存在平局,所以 K 和 H 约定由输的一方负责做饭。K 想知道,如果自己和 H 都足够聪明,那么以选中的图案进行的三步棋游戏是否为先手必胜;因为如果她更容易赢,她就要偷偷地给自己的妹妹放水。

输入:

从标准输入读入数据。

输入文件包含多组数据。

输入的第一行包含一个正整数 $T$,表示数据组数。保证 $1\le T\le 200$。

对于每组数据,输入包含 $5$ 行,每行包括一个长度为 $5$ 且仅含 .o 的字符串,表示指定的图案。保证每组数据中 o 至少出现一次,且所有 o 组成一个大小不超过 $4$ 的四连通块。

输出:

输出到标准输出。

对于每组数据输出一行。如果输入的图案为先手必胜,则输出 Far,否则输出 Away

样例1输入:
3
.....
oo...
.....
.....
.....
.o...
.o...
.....
.....
.....
.....
.....
.....
.ooo.
.....
样例1输出:
Far
Far
Away
样例1解释:

该样例包含三组数据。

第一组数据输入的图案为 $1$ 行 $2$ 列的 oo。显然,无论先手将棋子放在棋盘上的哪个位置,后手都只有两种策略:

  • 和先手的棋子连成 oo,此时棋盘上只有 $2$ 枚棋子,故后手立即输掉游戏;
  • 不和先手的棋子连成 oo,但是接下来轮到先手时,先手可以任意连成 oo,此时棋盘上恰有 $3$ 枚棋子,故先手取胜。

无论是哪种策略,后手都无法取胜,故对于 oo 而言先手必胜

第二组数据输入的图案为 $2$ 行 $1$ 列的图案,与 oo 同理,可知为先手必胜

第三组数据输入的图案为 $1$ 行 $3$ 列的 ooo,可以证明为先手必败。 子任务:

保证 $1\le T\le 200$。对于每组数据,保证输入的 $5\times 5$ 的由 .o 组成的字符矩阵中至少含有一个 o,且所有 o 组成一个大小不超过 $4$ 的四连通块。

思路:对于三,四可以先考虑不受边界影响的情况,然后根据图形形状去计算改变先后手的情况即可,最多9步即可得出博弈答案。


#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
//#include<bits/stdc++.h>
#include <unordered_map>
#define ll                               long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod =2;
const ll p=rnd()%mod;
const ll maxn=5e5+15;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		string f[500];
		ll ans=0;
		for(ll i=1;i<=5;i++)cin>>f[i],f[i]='0'+f[i];
		ll pd=0;
		for(ll i=1;i<=5;i++)
		{
			for(ll j=1;j<=5;j++)
			{
				ans+=(f[i][j]=='o');
				if(i>=2&&j>=2)
				{
					if(f[i][j]=='o'&&f[i-1][j]=='o'&&f[i][j-1]=='o'&&f[i-1][j-1]=='o')
					pd=1;
				}
				    if(j>=4)
					{
						if(f[i][j]=='o'&&f[i][j-1]=='o'&&f[i][j-2]=='o'&&f[i][j-3]=='o')
						pd=1;
					}
					if(i>=4)
					{
						if(f[i][j]=='o'&&f[i-1][j]=='o'&&f[i-2][j]=='o'&&f[i-3][j]=='o')
						pd=1;
					}
			}
		}
		if(ans==1)
		cout<<"Away"<<endl;
		else if(ans==2)
		cout<<"Far"<<endl;
		else if(ans==3)
		{
			cout<<"Away"<<endl;
		}
		else if(ans==4)
		{
			if(pd==1)
			cout<<"Away"<<endl;
			else
			cout<<"Far"<<endl;
		}
	}
}

M.你说得对,但是AIGC

题面:
你说得对,但是众所周知 AIGC 是当下计算机领域最热门的方向之一,算协的几名成员也对此很有兴趣,经过长时间的奋战,终于研发出了一款全新的语言大模型——ChatSAA。

你说得对,但是当模型即将发布之时,开发团队忽然发现模型存在重大问题——由于开发团队的某名成员沉迷于一款中文二字英文七字的游戏(见样例),导致训练模型时使用的语料库被莫名其妙地污染了,这使得模型生成的句子全都带有一个相同的前缀。

你说得对,但是紧急更换语料库重新训练显然已经来不及了,无奈开发团队只能在文档中注明:本模型的最大特性(而非bug)在于生成文本的前19个字符,这既是模型独特的防伪标记,也充分彰显了算协团队的人文情怀和文化素养。

你说得对,但是一个微不足道的问题在于:这会让人们一眼就能分辨出哪些句子是由 AI 生成的,这会对那些打算用 AI 来写作业的同学很不友好。

你说得对,但是现在你手里有一些句子,这些句子有的是由 ChatSAA 生成的,有的是人类写的(假设人类没有刻意模仿 ChatSAA 的生成特性),你需要写一个程序来辨别二者。
输入:
从标准输入读入数据。

你说得对,但是你的程序应当输入一行,一个字符串 $ s $ 表示需要判断的句子,满足 $ |s| \leq 200 $,且 $ s $ 由包括空格在内的 ASCII 可见字符(即 ASCII 码在 32~126 的字符)组成
输出:
输出到标准输出。

你说得对,但是你的程序应当输出一行,一个字符串表示判断结果,如果这句话是 AI 生成的,输出 AI,否则输出 Human。
样例:
You are right, but "Sao Lei (Winmine)" is a game whose Chinese name contains two characters while English name contains seven.
——————————
AI

Ni shuo de dui, dan shi zhe ju hua bu shi yi "You are right, but " kai tou de.
——————————
Human
,
You are wrong. Here is why. The English name of game "G****** I*****" contains 14 characters (including a space), not 7.


Human
思路:队友写的,检查前19个字符有没有“Yor are right,but”

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


string s="You are right, but ";
int main(){
	string str="";
	char x;
	int jd=1;
	while(scanf("%c",&x)!=EOF){
		str+=x;
		if(str.length()>=19){
			jd=0;
			for(int i=0;i<19;i++){
				if(s[i]!=str[i]){
					jd=1;
					break;
				}
			}	
		}
	}
	if(jd){
		printf("Human");
	}else{
		printf("AI");
	}
	
	return 0;
}
posted @ 2024-12-10 18:28  长皆  阅读(71)  评论(0)    收藏  举报