第十一周训练情况

第十一周训练情况

首先是A题

题目链接
https://vjudge.net/contest/439183#problem/A

当时的想法就是把a写成(0.5+)b;
ab=x;
(0.5+)
b*b=x;
然后根据x/b/b>0.5 逐渐提高b的值,最后拿到临界值。这时我们就得到了b的值
再从1到b遍历选中a的值即可。题目较简单 不作过多说明了,下边附上代码:

#include<bits/stdc++.h>
using namespace std;
//scanf("%d",&n);
int main()
{
  int n;
  scanf("%d",&n);
  for(int i=0;i<n;i++){
    double x;
    scanf("%lf",&x);
    long long int b;
    for(int j=1;;j++){
        if(x/j/j<0.5){
            b=j;
            break;
        }
    }
    int f=0;
    for(double j=1;j<=b;j++){
        for(double k=b;k>=j;k--){
            if(j*k<x)break;
            if(j*k==x&&j>=k*0.5){
                f=1;
                //cout<<"j: "<<j<<"k: "<<k<<endl;
                goto c;
            }
        }
    }

c:    if(f==1){
            cout<<1<<endl;
        }
        else cout<<0<<endl;

  }
  return 0;
}

G题

https://vjudge.net/contest/439183#problem/G
首先看到这道题,我还以为是要求面积的问题。

直接模拟了一次,每步加0.05但是,计算出来的面积的值相差太大。无奈直接重新看题,就发现面积是可以转换成公式的,上边是一个半圆,下边的式子也可以进行转换。而后化简之后用计算机实现,误差就小了很多

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define pi 3.1415926535897932384
int main() {
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        double a,b;
        cin>>a>>b;
        double temp1 = a*a*pi/2;
        double temp2 = 2*a*b;
        double temp3 = 2*b*pi*(asin(1)+asin(-1));
        cout<<(temp1 + temp2 -temp3)*2<<endl;
    }
    return 0;
}

B题

在这里插入图片描述

这道题是一个关于四个数字和三个字符随机排序的问题。

首先想到的是排列组合next_permutation函数,这个函数可以把数组元素进行排列组合。而后是考虑运算符在这四个排列之后的数值之间进行插入的问题。

注意这里可以分为连接,乘积,加减 运算符优先级从左到右。
相同优先级运算符运算顺序从左到右。
然后就想到用递归的方法枚举所有的情况,然后去重就可以得到最后的结果了。

代码如下:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 1e4 + 7;
int ans,vis[MAXN];/is记录答案
map<pair<vector<int>,int>,int>mp;
void dfs(vector<int>vec,int op){
	if(mp[{vec,op}]) return ;
	mp[{vec,op}]++;
	int siz = vec.size();
	if(siz == 1){
		if(!vis[vec[0]] && vec[0] >= 0) ans++,vis[vec[0]] = 1;
		// cout<<ans<<endl;
		return ;
	}
	if(op == 3){
		vector<int>t;
		t.push_back(vec[0] + vec[1]);
		for(int i = 2;i < siz;i ++) t.push_back(vec[i]);
		dfs(t,op);

		t[0] = vec[0] - vec[1];

		dfs(t,op);
	}
	if(op == 1 || op == 2){
		dfs(vec,op+1);
		if(siz == 2 && op == 1) return ;
		for(int i = 0;i < siz - 1;i ++){
			vector<int>t;
			for(int j = 0;j < i;j ++) t.push_back(vec[j]);
			if(op == 2){
				t.push_back(vec[i] * vec[i+1]);
			}
			else if(op == 1){
				t.push_back(vec[i+1] >= 10 ? vec[i]*100 + vec[i+1] : vec[i] * 10 + vec[i+1]);
			}
			for(int j = i + 2;j < siz;j ++) t.push_back(vec[j]);
			dfs(t,op);
		}
	}
} 
int main(){
	vector<int>vec;
	int x;
	for(int i = 1;i <= 4;i ++) scanf("%d",&x),vec.push_back(x);
	sort(vec.begin(),vec.end());
	do{
		dfs(vec,1);
		// cout<<ans<<endl;
	}while(next_permutation(vec.begin(),vec.end()));
	printf("%d\n",ans);
	return 0;
}

而后看到了某带佬的巨作,直接暴力插入set中去重,太强了。但是他的逻辑我还没理清,有空回来看看。

int main() {
    IOS; rep (i, 0, 3) cin >> a[i]; sort(a, a + 4);
    st.insert(a[0] + a[1] + a[2] + a[3]);
    st.insert(a[0] * a[1] * a[2] * a[3]);
    do {
        st.insert(abs(a[0] + a[1] + a[2] - a[3]));
        st.insert(abs(a[0] + a[1] - a[2] - a[3]));
        st.insert(a[0] * a[1] + a[2] + a[3]);
        st.insert(a[0] * a[1] + a[2] * a[3]);
        st.insert(abs(a[0] * a[1] - a[2] - a[3]));
        st.insert(abs(a[0] * a[1] - a[2] + a[3]));
        st.insert(abs(a[0] * a[1] - a[2] * a[3]));
        st.insert(a[0] + a[1] * a[2] * a[3]);
        st.insert(abs(a[0] - a[1] * a[2] * a[3]));
        st.insert(a[0] * 10 + a[1] + a[2] + a[3]);
        st.insert(a[0] * 10 + a[1] + a[2] * a[3]);
        st.insert(abs(a[0] * 10 + a[1] - a[2] - a[3]));
        st.insert(abs(a[0] * 10 + a[1] - a[2] + a[3]));
        st.insert(abs(a[0] * 10 + a[1] - a[2] * a[3]));
        st.insert((a[0] * 10 + a[1]) * a[2] + a[3]);
        st.insert((a[0] * 10 + a[1]) * a[2] - a[3]);
        st.insert((a[0] * 10 + a[1]) * a[2] * a[3]);
        st.insert(a[0] * 100 + a[1] * 10 + a[2] + a[3]);
        st.insert(a[0] * 100 + a[1] * 10 + a[2] - a[3]);
        st.insert((a[0] * 100 + a[1] * 10 + a[2]) * a[3]);
        st.insert((a[0] * 10 + a[1]) + (a[2] * 10 + a[3]));
        st.insert(abs((a[0] * 10 + a[1]) - (a[2] * 10 + a[3])));
        st.insert((a[0] * 10 + a[1]) * (a[2] * 10 + a[3]));
    } while (next_permutation(a, a + 4));
    cout << st.size();
    return 0;
}

补题:

在这里插入图片描述

J题

本来这道题我刚拿到题,想到的是这跟数值分解因数有一定的关系。然后就在分析能分解的因数的层数,然后就发现问题越分析越复杂。知道后面代码就非常的麻烦,就感觉思路出现了问题。

而后认为从头分析太复杂,就从最后分析,发现最后能判定输赢的时候都是遇到了一个质数。而想要能够选择的质数的最大值,那么是不是就我们选择的数应该是一个质数乘上一个质数的形式。而后有解

具体代码如下:

#include <iostream>
#include <bits/stdc++.h>
#define ref(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int preme[200000]={0};
bool pre[200000]={0};
int cnt=0;
void su(int t){
    ref(i,0,1)pre[i]=false;

    ref(i,2,t){
        if(pre[i]==false){
            preme[cnt++]=i;
        }
        for(int j=i+i;j<=t;j=j+i){
            pre[j]=true;
        }


    }
}

bool sushu(int x){
    if(pre[x]==false)return true;
    return false;
}

bool cj(int x){
    int sq= sqrt(x);
    ref(i,2,sq){
        if(x%i==0)
        if(sushu(i)&&sushu(x/i))return true;
    }
    return false;
}


int ma(int a){
    if(a==1)
        return 1;
    else
    {
        for(int i=2; i*i<=a; i++)
        {
            if(a%i==0)
            {
                return ma(a/i)>ma(i)?ma(a/i):ma(i);
            }
        }
        return a;
    }
}

int main()
{
    su(100000);
    int n;
    scanf("%d",&n);

    //ref(i,0,100)cout<<preme[i]<<endl;
    ref(i,1,n){
        int x;
        scanf("%d",&x);
        if(sushu(x)) printf("0\n");
        else if(cj(x)) printf("-1\n");
        else {
            ma(x);
          //  cout<<ma(x)<<"   11111"<<endl;
            for(int i=x/ma(x);i>=2;i--){
                if(sushu(i)&&x%(i*ma(x))==0){
                    printf("%d\n",i*ma(x));
                    break;
                }
            }

        }

    }
    return 0;
}

C题

在这里插入图片描述

最开始的想法,从左到右消除,然后纸上模拟了一下就感觉有些问题。
比如AAAABBBA m=3的话,按上边的思路来的话就不太行。

最后看了大佬的代码,动态规划区间DP。
然后就仔细学了区间DP,根据长度和首个字母的位置。两层嵌套for循环,再带上中间的状态转移方程。
借鉴学习学习。

#include <iostream>
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dec(i,a,b) for(int i=a;i>=b;i--)
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=505;
int a[maxn];
int sz,m;
string t="RGBCMYK",s;
int dp [maxn][maxn][7],id[maxn];
//BBBRRRRRRGGGB 3
int main() {
    cin>>s>>m;
    if(m==1){
        cout<<"Yes";
        return 0;
    }
    memset(dp,-INF,sizeof(dp));
    rep(i,0,t.size()-1)id[t[i]]=i;

    rep(i,0,s.size()-1)dp[i][i][id[s[i]]]=1;
    rep(len,2,s.size())rep(l,0,s.size()-len){
        int r=l+len-1;
        bool mer =0;
        rep(i,l,r-1)rep(k,0,6)
        {
            dp[l][r][k]=max(dp[l][r][k],dp[l][i][k]+dp[i+1][r][k]);
            //if(l==6&&r==7) cout<<l<<" "<<i<<" "<<k<<" "<<dp[l][i][k]<<" "<<i+1<<" "<<r<<" "<<dp[i+1][r][k]<<endl;
            //cout<<dp[l][r][k]<<endl;
            //cout<<l<<" "<<r<<" "<<dp[l][r][k]<<endl;
            if(dp[l][r][k]>=m){
                mer=1;
                //cout<<"l and r "<<l<<" "<<r<<endl;
            }

        }
        if(mer)rep(k,0,6)dp[l][r][k]=max(dp[l][r][k],0);
    }
   /* rep(k,0,6){
        cout<<dp[0][s.size()-1][k]<<endl;
    }*/
    rep(k,0,6)if(dp[0][s.size()-1][k]>=m){
        cout<<"Yes";
        return 0;
    }
    cout<<"No";

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

while WA er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值