2024.11.20组队训练记录

B . osu!mania

题面:
\( pp = \max\left(0, \frac{320a + 300b + 200c + 100d + 50e + 0f}{320(a + b + c + d + e + f)} - 80\% \right) \times 5 \times ppmax \)
输入:
输入的第一行包含一个正整数 $ T $ ,表示数据组数。保证 $ 1 \leq T \leq 100 $ 。

对于每组测试数据:

输入的第一行包含一个非负整数 $ ppmax $。保证 $ 0 \leq ppmax \leq 3000 $。

输入的第二行包含六个非负整数 $ a, b, c, d, e, f $,含义如题目描述所示。保证 $ 0 \leq a, b, c, d, e, f \leq 2 \times 10^4 $ 且 $ a+b+c+d+e+f \geq 1 $。
输出:

对于每组测试数据:输出一行两个数,以空格隔开。其中第一个数表示准确率,以百分数形式输出,精确到 \(10^{-4}\);第二个数为个人表现,以整数形式输出。
样例:
2
630
3029 2336 377 41 10 61
3000
20000 10000 0 0 0 0
————————
96.20% 423
100.00% 2688
思路:就是按公式计算,这里要四舍五入,这里采用除数乘回答案和除数乘(答案+1),然后用差值绝对值谁最小就靠近谁,这样就避免了精度损失

#include<bits/stdc++.h>
#define test(i) cout << #i << " "<< i << " " << endl;
#define endl '\n'

using namespace std;
typedef long long ll;

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

ll t,n;

void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

void print(double a1,ll a2){
	a1*=100;
	printf("%.2lf",a1);
	cout << "%" << " ";
	printf("%lld",a2);
	cout << endl;
}

void solve(){
	double pp;
	cin >> pp;
	long double a[10],b[]={300,300,200,100,50,0};
	ll c[]={320,300,200,100,50,0};
	for(int i=0; i<6; i++){
		cin >> a[i];
	}
	double ans1=0;
	ll ans2=0;
	double tmp=0;
	for(int i=0; i<6; i++){
		ans1+=a[i]*b[i];
		tmp+=a[i];
	}
	ans1/=tmp*300;
	for(int i=0; i<6; i++){
		ans2+=a[i]*c[i];
	}
	ans2-=256*tmp;
	ans2=ans2*5*pp;
	if(ans2<0) print(ans1,0);
	else{
		ll tt=ans2;
		tt/=320*tmp;
		ll t1=tt,t2=tt+1;
		if(llabs(t1*320*tmp-ans2)>=llabs(t2*320*tmp-ans2)) print(ans1,t2);
		else print(ans1,t1);
	}
	
}

signed main()
{
	//fio();
	cin >> t;
	//t=1;
	while(t--){
		solve();
	}
	return 0;
}

C.连方

题面:
给定正整数 $ n $ 和两个仅包含字符 .# 的长度为 $ n $ 的字符串 $ a, b $,请构造一个 $ 7 \times n $ 的仅包含字符 .# 的矩阵,满足以下条件:

  • 矩阵第 1 行与 $ a $ 相同,第 7 行与 $b $相同。
  • 由四方向连通的 # 构成的图形均为实心的矩形。具体地:
    • 对于两个 # 字符,如果可以从其中一个 # 字符出发,在有限步之内仅经过 # 字符到达另一个 # 字符,其中每一步均为向上、左、下、右四个方向之一移动一格,则称这两个 # 字符在同一组。那么,由同一组内的所有 # 字符构成的图形均为实心的矩形。
  • 所有的 # 字符八方向连通,具体地:
    • 对于任意两个 # 字符,均可以从其中一个 # 字符出发,在有限步之内仅经过 # 字符到达另一个 # 字符,其中每一步均为向上、左、下、右、左上、右上、左下、右下八个方向之一移动一格。

请输出任意一个满足条件的矩阵,或判定无解。
输入:
从标准输入读入数据。

输入的第一行包含一个正整数 $ T (1 \leq T \leq 10^4) $,代表数据组数。

每组数据第一行包含一个正整数 $ n (2 \leq n \leq 10^5) $,代表矩阵的宽度。

接下来两行分别包含仅包含字符 .#,长度为 $ n $ 的两个字符串 $ a, b $,代表矩阵的第 1 行与第 7 行。

保证 $ a $与 $ b $均包含至少一个 #

保证单个测试点内所有$ n$ 的总和不超过$ 2 \times 10^5$。
输出:
输出到标准输出。
对于每组测试数据,如果不存在满足要求的矩阵,则输出一行一个字符串 No。
如果存在满足要求的矩阵,则先输出一行一个字符串 Yes,然后输出 7 行,每行包
含一个长度为 n 的字符串,代表你构造的矩阵。
思路:本题构造思路不难,对于列大于等于2后,只要一个字符串全为#,另一个字符串有.且有#则一定无解。
特判列为1时情况,然后对列大于等于2以后再满足基本情况下(字符串#如果旁边是. 就在.附近构造#)就是考虑构造一条通路即可。不难写,但是分类多。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int x[10][100005]={0};
void solve(){
	int n;
	scanf("%d",&n);
	string a;
	string b;
	cin>>a>>b;
	int jd1=0,jd11=0;
	int jd2=0,jd22=0;
	int st1=0,st2=0;
	for(int i=1;i<=7;i++){
		for(int j=1;j<=n;j++){
			x[i][j]=0;
		}
	}
	for(int i=0;i<n;i++){
		if(a[i]=='.'){
			jd1=1;
			if(st1==0&&i>0)st1=i+1;
			x[1][i+1]=0;	
		}else{
			jd11=1;
			x[1][i+1]=1;	
		}
	}
	for(int i=0;i<n;i++){
		if(b[i]=='.'){
			jd2=1;
			if(st2==0&&i>0)st2=i+1;
			x[7][i+1]=0;	
		}else{
			jd22=1;
			x[7][i+1]=1;
		}
	}
	if(jd1==1&&jd11==1&&jd2==0){
		printf("No\n");
		return ;
	}
	if(jd1==0&&jd22==1&&jd2==1){
		printf("No\n");
		return ;
	}
	printf("Yes\n");
	if(jd11==0&&jd2==0){
		cout<<a<<"\n";
		for(int i=2;i<=7;i++){
			for(int j=1;j<=n;j++){
				printf("#");
			}
			printf("\n");
		}
		return ;
	}
	if(jd1==0&&jd22==0){
		for(int i=1;i<=6;i++){
			for(int j=1;j<=n;j++){
				printf("#");
			}
			printf("\n");
		}
		cout<<b<<"\n";
		return ;
	}
	if(jd1==0&&jd2==0){
		for(int i=1;i<=7;i++){
			for(int j=1;j<=n;j++){
				printf("#");
			}
			printf("\n");
		}
		return ;
	}
	for(int i=2;i<=n;i++){
		if(a[i-1]=='.'){
			x[2][i]=1;
		}
	}
	for(int i=2;i<st1;i++){
		x[3][i]=1;
	}
	if(st1==2){
		x[3][1]=1;
	}else if(st1<=1){
		x[3][1]=1;x[2][1]=1;
	}
	if(st2==2){
		x[5][1]=1;
	}else if(st2<=1){
		x[6][1]=1;x[5][1]=1;		
	}
	x[4][1]=1;
	for(int i=2;i<=n;i++){
		if(b[i-1]=='.'){
			x[6][i]=1;
		}
	}
	for(int i=2;i<st2;i++){
		x[5][i]=1;
	}
	cout<<a<<"\n";
	for(int i=2;i<=6;i++){
		for(int j=1;j<=n;j++){
			if(x[i][j]==1){
				printf("#");
			}else{
				printf(".");
			}
		}
		printf("\n");
	}
	cout<<b<<"\n";
	return ;
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		solve();
	}
	return 0;
}

E.合成大西瓜

题面:
小白有 $ n $ 个西瓜(保证 $ n $是奇数),每个西瓜有个重量 $ a_i $。她在这 $n $ 个西瓜之间建立了 $ m $ 条无向边,使任意两个西瓜之间都至少存在一条路径能到达。

小白现在可以选择三个西瓜进行合并,具体地,她会选择三个不同的西瓜$ x, y, z $ 满足$ x, y $ 之间有一条无向边\(y,z\)之间有一条无向边。她会得到一个新的西瓜 $ w$ ,其重量\(a_w\)= $max(a_y, \min(a_x, a_z)) $。接下来,她对于“至少和 $ x, y, z $ 中某个西瓜之间有无向边”的西瓜 $ t $,建立了一条 $(w, t) $ 之间的无向边。最后,小白删去了 $ x, y, z$ 三个西瓜以及某一端为 $ x, y, z$的无向边。

可以证明一定存在一种合并 $\frac{n-1}{2} $ 次的方案使得最后仅剩下一个西瓜,小白想知道最后那个西瓜重量的最大值是多少。
输入:
从标准输入读入数据。

第一行两个非负整数 $ n, m $。保证 $ 1 \leq n \leq 10^5, 0 \leq m \leq 10^5 $,且 $n $ 是奇数。

第二行 $ n $ 个正整数$a_1, a_2, \ldots, a_n $,表示每个西瓜的重量。保证 $ 1 \leq a_i \leq n $。

接下来$ m $ 行,每行两个正整数 $ x, y $ 表示图上的一条无向边 $ (x, y) $。保证 $ 1 \leq x, y \leq n $ 且 $x \neq y $。

保证给定的无向图连通,且无重边与自环。
输出:
输出到标准输出。
一行一个正整数,表示答案。
样例:
7 7
1123121
1 2
2 3
1 3
2 4
2 5
5 6
5 7
————
2

1 0
—————
1
思路:对于读度大于等于2的点,他一定可以成为最后三点的中心点。对于度为1的点他只能成为最后三点的外点,所以最后在度为二的点的最大值和度为1的点的的第二大值取个max即可。特判一节点情况

#include<bits/stdc++.h>
#define test(i) cout << #i << " "<< i << " " << endl;
#define endl '\n'

using namespace std;
typedef long long ll;

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

ll t;
ll w[N],in[N];
vector<ll> G[N],V[N];

void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

void solve(){
	ll n,m,u,v;
	cin >> n >> m;
	for(int i=1; i<=n; i++)cin >> w[i];
	if(n==1){
		cout << w[1] << endl;
		return;
	}
	for(int i=1; i<=m; i++){
		cin >> u >> v;
		in[u]++;
		in[v]++;
		G[v].push_back(u);
		G[u].push_back(v);
	}
	ll ans=0;
	ll fir=0,sec=0;
	for(int i=1; i<=n; i++){
		if(in[i]<2){
			if(fir<=w[i]){
				sec=fir;
				fir=w[i];
			}
			else if(sec<=w[i]){
				sec=w[i];
			}		
			continue;
		}
		ans=max(ans,w[i]);
	}
	ans=max(ans,sec);
	cout << ans << endl;
}

signed main()
{
	//fio();
	//cin >> t;
	t=1;
	while(t--){
		solve();
	}
	return 0;
}

I.算术

题面:
Menji学习了加法和乘法。

Menji有一些写着 \(1\sim 9\) 的卡片,其中写着 \(i\) 的有 \(a_i\) 张。

Menji每次会选择两张卡片,并选择将他们的和或者他们的积写在一张新的卡片上,之后他会丢弃选择的两张卡片,并拿起新的一张卡片。

可以发现,经过 \(\left(\sum_{i=1}^{9} a_i\right)-1\) 轮操作之后,Menji手上只剩下一张卡片,Menji想要最大化这张卡片上数字的值,但由于卡片数量太少,Menji无法独立完成这个任务,希望你能帮他求出最后的数字最大能是多少。

由于本题答案很大,你只需要输出答案对 998244353 取模后的值。注意,你需要输出的是最大值 mod 998244353,而不是 mod 998244353 意义下的最大值。
输入:
从标准输入读入数据。

本题含有多组测试数据。第一行一个正整数 $ T (1 \leq T \leq 1000) $,表示数据组数。

之后 $ T $ 行,每行 9 个非负整数 $ a_1, a_2, \ldots, a_9 (0 \leq a_i \leq 100, \sum_{i=1}^9 a_i \geq 1) $。
输出:
输出 T 行,其中第 i 行是第 i 组数据中最终剩余的数的最大值对 998244353 取模
的结果。
7
5 3 0 0 0 0 0 0 0
4 1 1 1 0 0 0 0 0
1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 2
99 88 77 66 55 44 33 22 11
8 100 90 80 70 60 50 40 30 20
————————
54
108
1
10
90
90553232
143532368
思路:
本题可以先通过样例得到,当有1时最好先把2转成3,如果1还有剩余就把他自己给合成为2,然后再耗费1进行2变3操作.如果最后1还有剩余,就遍历下3到9看看能否加1,如果可以加1就加上,最后用快速幂计算(2~10)答案值。如果还剩了1就直接最后答案++就行了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll qm(ll a,ll x){
	ll ans=1;
	while(x){
		if(x%2){
			ans=(ans%mod)*(a%mod)%mod;
		}
		a=(a%mod)*(a%mod)%mod;
		x/=2;
	}
	return ans%mod;
}
ll a[100]={0};
void solve(){
	for(int i=1;i<=9;i++) scanf("%lld",&a[i]);
	int jd=0;
	for(int i=2;i<=9;i++){
		if(a[i]>0){
			jd=2;
		}
	}
	if(a[1]>1){
		jd=2;
	}
	a[10]=0;
	while(a[1]>1){
		if(a[2]>1){
			a[2]-=2;a[3]+=2;
			a[1]-=2;
		}else{
			a[1]-=2;
			a[2]++;
		}
	}
	for(int i=2;i<=9&&a[1]>0;i++){
		if(a[i]>0){
			a[i]--;
			a[i+1]++;
			a[1]=0;
			break;
		}
	}
	ll ans=1;
	for(ll i=2;i<=10;i++){
		ll tem=qm(i,a[i]);
		ans=(ans%mod)*(tem%mod)%mod;
	}
	if(jd==2&&a[1]==1){
		ans++;
	}
	ans%=mod;
	printf("%lld\n",ans);
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		solve();
	}
	return 0;
}

J . 骰子

这里图我没粘到,偷个懒,直接截图
题面:
image
输入:
从标准输入读入数据。
输入一行两个整数$ n, m (2 ≤ n, m ≤ {10^3})$,表示网格的长和宽
输出:
输出一行一个整数,表示在进行任意多次操作后,网格上所有写过数字的格子的数
字的和的最大值。
样例:
2 2
输出
24
思路:显然n>=2且m>=2,且题目样例答案为24.可以把这个\(2*2\),图视作任意给出的图的子图,显然具有一定的传递性,直接\(n*m*6\)

#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>
#define ll                                     long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
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;
   t=1;
   while(t--)
   {
	ll n,m;
	cin>>n>>m;
	cout<<n*m*6<<endl;
   }
}

K.小 C 的神秘图形

题面:
对于正整数 $ n $,定义一个 $ 3^n \times 3^n $ 的 01 矩阵 $ A_n $:

  • 若 $3^{n-1} \leq i < 2 \times 3^{n-1} $ 或者 $ 3^{n-1} \leq j < 2 \times 3^{n-1} $,则

$ A_n(i, j)$ = \(\left\{ \begin{array}{ll} 1, & n=1, \\ A_{n-1}(i \mod 3^{n-1}, j \mod 3^{n-1}), & n \geq 2. \end{array} \right.\)

其中 $ x \mod y $ 表示 $ x $ 对 $ y $ 取模后的结果。

  • 否则,$ A_n(i, j) = 0 $。

给定正整数 $ n $,小 C 有两个长度为 $ n $ 的数字串,代表两个三进制数 $ n_1, n_2 $。需要求出 $ A_n(n_1, n_2) $ 的值。
输入:
第一行输入一个正整数 n(1 ≤ n ≤ 105),含义见题目描述。
接下来两行,每行输入一个长度为 n 的数字串,分别表示三进制数 n1, n2。
输出:
输出一个整数,表示 An(n1, n2) 的值。
样例:
2
20
01
——————
0

3
102
011
——————
1
思路:
这里从左到右看上下是否有个数字为1就行了,如果对于每个位置都有1,则输出1
否则输出0。具体证明方法不不知道,这个是由队友给出的。这里看看打表后的9*9矩阵位置值为1的x与y坐标的三进制应该可以得出这个推论。

#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>
#define ll                                     long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 3;
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);
}
ll a[40][40];
ll b[40][40];
int main()
{
   fio();
   ll t;
   ll n;
   cin>>n;
   string f1,f2;
   cin>>f1>>f2;
   ll n1,n2;
   ll pd=1;
   for(ll i=0;i<n;i++)
   {
	if(f1[i]=='1'||f2[i]=='1')
	{
continue;
	}
	else 
	pd=0;
   }
   if(pd)
   cout<<1<<endl;
   else cout<<0<<endl;
}

posted @ 2024-11-21 15:51  长皆  阅读(11)  评论(0编辑  收藏  举报