【无标题】2024.4.7

2024.4.7 【南天寂静亮星少,北落师门赛明灯。】

Sunday 二月三十


<theme = oi-“search”>

A. 填充单词

题目描述
小C认识很多单词,但是他并不喜欢其中的一些单词。具体地说,如果一个单词包含连续的3个元音字母,或连续的3个辅音字母,或者1个“L”字母都不包含的话,这个单词是不被小C喜欢的。其中元音字母仅为A、E、I、O、U这5个字母,剩下的字母全部为辅音字母。

现在给你一个部分残缺的单词,问一共有多少种方法用26个字母来填满这个单词,使得小C是喜欢这个单词的?

格式
输入格式
输入仅一行包括 1 个长度不超过100 的全部由字符串,表示残缺的单词,其中残缺的部分用’_’ 表示。

输出格式
输出仅一行,包括1 个正整数,表示不同的方案数。这个数字可能会很大,请用long long存储。

Samples
输入数据 1

L_V

输出数据 1

5

输入数据 2

V__K

输出数据 2

10

输入数据 3

JA_BU_K_A

输出数据 3

485

数据范围与提示
10组测试数据下划线的个数为3,5,6,7,9,10,10,10,10,10
搜索做法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
ll ans;int cnt,tl;
char w[30]={'A','E','I','O','U','y','f'};
bool yuan(char d){
	for(int i=0;i<6;++i){
		if(d==w[i])return 1;
	}
	return 0;
}
ll ksm(ll a,ll b){
	ll num=1;
	while(b>0){
		if(b&1)num=num*a;
		a=a*a;
		b>>=1;
	}
	return num;
}
void dfs(int p,int y,int ty,int t_y){
	if(p>int(s.size())-1){
		if(tl==1){
			ans+=ksm(5,t_y)*ksm(21,cnt-t_y);
		}
		else ans+=ksm(5,t_y)*(ksm(21,cnt-t_y)-ksm(20,cnt-t_y));
		return;
	}
	if(yuan(s[p])){
		ty=max(1,ty); 
		if(y==p-1&&y!=0){
			++ty;
			if(ty==3)return;
		}
		y=p;
	}
	else{
		ty=0;
	}
	if(p-y>=3)return;
	if(s[p+1]=='_'){
		s[p+1]='y';
		dfs(p+1,y,ty,t_y+1);
		s[p+1]='f';
		dfs(p+1,y,ty,t_y);
		s[p+1]='_';
	}
	else dfs(p+1,y,ty,t_y);
	return;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	//freopen("A.in","r",stdin);
	//freopen(".out","w",stdout);
	cin>>s;
	s='0'+s;
	for(int i=1;i<=int(s.size())-1;++i){
		if(s[i]=='_')++cnt;
		if(s[i]=='L')tl=1;
	}
	dfs(0,0,0,0);
	cout<<ans<<endl;
	return 0;
}

DP做法

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 110;
ll dp[maxn][5][2];
char s[maxn];
int main(){
	cin>>s;
	int n = strlen(s);
	for(int i = n;i > 0;i--){
		s[i] = s[i-1];
	} 
	if(s[1] == '_'){
		dp[1][1][0] = 0,dp[1][2][0] = 0,dp[1][3][0] = 5,dp[1][4][0] = 20;
		dp[1][1][1] = 0,dp[1][2][1] = 0,dp[1][3][1] = 0,dp[1][4][1] = 1;
	}
	else if(s[1] == 'A'||s[1] == 'E'||s[1] == 'I'||s[1] == 'O'||s[1] == 'U'){
		dp[1][1][0] = 0,dp[1][2][0] = 0,dp[1][3][0] = 1,dp[1][4][0] = 0;
		dp[1][1][1] = 0,dp[1][2][1] = 0,dp[1][3][1] = 0,dp[1][4][1] = 0;
	}
	else if(s[1] == 'L'){
		dp[1][1][0] = 0,dp[1][2][0] = 0,dp[1][3][0] = 0,dp[1][4][0] = 0;
		dp[1][1][1] = 0,dp[1][2][1] = 0,dp[1][3][1] = 0,dp[1][4][1] = 1;
	}
	else{
		dp[1][1][0] = 0,dp[1][2][0] = 0,dp[1][3][0] = 0,dp[1][4][0] = 1;
		dp[1][1][1] = 0,dp[1][2][1] = 0,dp[1][3][1] = 0,dp[1][4][1] = 0;
	}
	
	for(int i = 2;i <= n;i++){
		if(s[i] != '_'){
			if(s[i] == 'A'||s[i] == 'E'||s[i] == 'I'||s[i] == 'O'||s[i] == 'U'){
				dp[i][1][0] = dp[i-1][3][0];
				dp[i][2][0] = 0;
				dp[i][3][0] = dp[i-1][2][0]+dp[i-1][4][0];
				dp[i][4][0] = 0;
				dp[i][1][1] = dp[i-1][3][1];
				dp[i][2][1] = 0;
				dp[i][3][1] = dp[i-1][2][1]+dp[i-1][4][1];
				dp[i][4][1] = 0;
			}
			else{
				if(s[i] == 'L'){
					dp[i][1][0] = 0;
					dp[i][2][0] = 0;
					dp[i][3][0] = 0;
					dp[i][4][0] = 0;
					dp[i][1][1] = 0;
					dp[i][2][1] = dp[i-1][4][1]+dp[i-1][4][0];
					dp[i][3][1] = 0;
					dp[i][4][1] = dp[i-1][1][1]+dp[i-1][1][0]+dp[i-1][3][0]+dp[i-1][3][1];
				}
				else{
					dp[i][1][0] = 0;
					dp[i][2][0] = dp[i-1][4][0];
					dp[i][3][0] = 0;
					dp[i][4][0] = dp[i-1][1][0]+dp[i-1][3][0];
					dp[i][1][1] = 0;
					dp[i][2][1] = dp[i-1][4][1];
					dp[i][3][1] = 0;
					dp[i][4][1] = dp[i-1][1][1]+dp[i-1][3][1];
				}
			}	
		}
		else{//j: 1 2y    2 2f    3 y    4 f
			dp[i][1][0] = dp[i-1][3][0]*5;
			dp[i][2][0] = dp[i-1][4][0]*20;
			dp[i][3][0] = dp[i-1][2][0]*5+dp[i-1][4][0]*5;
			dp[i][4][0] = dp[i-1][1][0]*20+dp[i-1][3][0]*20;
			dp[i][1][1] = dp[i-1][3][1]*5;
			dp[i][2][1] = dp[i-1][4][1]*21+dp[i-1][4][0];
			dp[i][3][1] = dp[i-1][2][1]*5+dp[i-1][4][1]*5;
			dp[i][4][1] = dp[i-1][1][1]*21+dp[i-1][3][1]*21+dp[i-1][1][0]+dp[i-1][3][0];
		}
	}
	/*
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= 4;j++){
			cout<<dp[i][j][0]<<"|"<<dp[i][j][1]<<" ";
		}
		cout<<endl;
	}
	*/
	cout<<dp[n][1][1]+dp[n][2][1]+dp[n][3][1]+dp[n][4][1];
}

B. 解方程

题目描述
考虑以下的方程形式:
a ∗ x 1 2 + b ∗ x 2 2 + c ∗ x 3 2 + d ∗ x 4 2 = 0 a * x^2_1+b * x^2_2+c * x^2_3+d * x^2_4 = 0 ax12+bx22+cx32+dx42=0
a,b,c,d是区间[-50,50]内的整数。

求满足以下条件的方程解
( x 1 , x 2 , x 3 , x 4 ) (x_1,x_2,x_3,x_4) (x1,x2,x3,x4)
的个数:x是区间[-100,100]内的非零整数。

格式
输入格式
单组输入数据,输入四个整数,表示a,b,c,d

输出格式
输出一个整数,表示解的个数。

Samples
输入数据 1

1 2 3 -4

输出数据 1

39088

输入数据 2

1 1 1 1

输出数据 2

0

数据范围与提示

对于5%的数据,a,b,c,d均为 0;

对于另外10%的数据,a,b,c,d中有 3 个 0 ;

对于另外25%的数据,a,b,c,d中有 2 个 0 ;

对于另外30%的数据,a,b,c,d中有 1个 0 ;

对于剩余30%的数据,无特殊限制 ;

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a,b,c,d;
    long long count = 0;
    cin >> a >> b >> c >> d;
    for(int x1 = 1;x1 <= 100;x1++)
        for(int x2 = 1;x2 <= 100;x2++)
            for(int x3 = 1;x3 <= 100;x3++)
                for(int x4 = 1;x4 <= 100;x4++)
                    if(a * x1 * x1 + b * x2 * x2 + c * x3 * x3 + d * x4 * x4 == 0) count++;
    cout << count * 16 << endl;
    return 0;
}

不需要过多思考,直接暴力啊。


C. AB数字游戏

题目描述
小C和小T又在玩数字游戏了。这次的规则是这样的:最开始有两个空的数列 A 和 B,第 i 次小T会给数列 A 和 B 分别加上一个数 A i , B i A_i,B_i Ai,Bi,而小C可以将 A 和 B 以任意方式重新排序,使得 A i + B i A_i+B_i Ai+Bi 的最大值最小。

请你帮小C在每一次小T给出两个新的数之后,求出最大值的最小值。

格式
输入格式
第一行包括 1 个正整数 N,表示小T给出数字的次数。

接下来 N 行,第 i+1 行包括 2 个正整数 A i , B i A_i,B_i Ai,Bi,表示每次一小T给出的数对。

输出格式
输出包括 N 行,对于每一次小T 给出的数字,求出所求排列中对应 A 和 B 之和的最大值的最小值。

样例
输入数据 1

3
2 8
3 1
1 4

输出数据 1

10
10
9

输入数据 2

3
1 1
2 2
3 3

输出数据 2

2
3
4

数据范围与提示
对于 50%的数据,有 N≤200,

对于 100%的数据,有 1≤N≤100000,1≤A,B≤100。

第一组样例解释:

第一次询问:A = {2}, B = {8},MIN{Ai + Bi}=2+8=10;

第二次询问:A = {2,3}, B = {8,1},MIN{Ai + Bi}=2+8=10;

第三次询问:A = {1,2,3}, B = {8,1,4},MIN{Ai + Bi}=1+8=9;

//Zn
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;
int n,ta,tb,ans,l,r,tot,t;
int a[110],b[110];
int c[110],d[110];
int main()
{
    ios::sync_with_stdio(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>ta>>tb;
        a[ta]++;
        b[tb]++;
        ans=0;
        for(int i=1;i<=100;i++)
            c[i]=a[i];
        for(int j=1;j<=100;j++)
            d[j]=b[j];
        l=1;
        r=100;
        tot=0;
        while(tot<i*2)
        {
            while((!c[l])&&l<100) l++;
            while((!d[r])&&r>1) r--;
            t=min(c[l],d[r]);
            ans=max(ans,l+r);
            tot+=t*2;
            c[l]-=t;
            d[r]-=t;
        }
        cout<<ans<<'\n';
    }
    return 0;
}

D. 可交换数字最大连续和

题目描述
一个长度为n 数组 A 的最大连续和,是指所有满足 1 ≤ L ≤ R ≤ n 1≤L≤R≤n 1LRn 的 a[i]和的最大值。一次交换操作是指:(1) 选择两个下标 i 和(i∗j)(2) 进行赋值,$tmp=A[i],A[i]=A[j],A[j]=tmp $;

给定一个长度为 n 的数组, 最多进行 m 次交换操作后,该数组的最大连续和。

输入格式
第一行两个两个整数 n和m。

第二行n 个数字,表示数组中的元素。

输出格式
输出答案。

样例
输入数据 1

10 2
10 -1 2 2 2 2 2 2 -1 10

输出数据 1

32

输入数据 2

5 10
-1 -1 -1 -1 -1

输出数据 2

-1

第四题没人解出来。。。。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值