YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

A题  签到

B题  统计1的个数与6的个数,当6的个数-1的个数>=1时,1的个数就是答案

#include<bits/stdc++.h>
using namespace std;
 
int main()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    int a1=0,a6=0;
    for(int i=0;i<n;i++){
        if(s[i]=='1') a1++;
        if(s[i]=='6') a6++;
    }
    for(int i=a1;i>=0;i--){
        if(a6-i>=1){
            cout<<i<<endl;
            return 0;
        }
    }
    cout<<0<<endl;
    return 0;
}

 

C题

期望DP   dp[i][j]表示前i个题中,恰好做对了j道题,所以dp[i][j]=dp[i-1][j]*(1-p[i])+dp[i-1][j-1]*p[i]。然后初始化dp[0][0]=1与dp[i][0]。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll N=2E3+7;
ll arr[N];
ll dp[N][N];
int main(){
    ll n;
    cin>>n;
    for(ll i=1;i<=n;i++) cin>>arr[i];
    dp[0][0]=1;
    for(ll i=1;i<=n;i++) dp[i][0]=dp[i-1][0]*((1-arr[i]+mod)%mod)%mod;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            dp[i][j]=(dp[i-1][j]*((1-arr[i]+mod)%mod)%mod+dp[i-1][j-1]*arr[i]%mod)%mod;
        }
    }
    for(int i=0;i<=n;i++) {
        cout<<dp[n][i]<<" ";
    }


    return 0;
}

D:

暴力枚举没三个点,当三个点满足不在同一条直线上,并且其中一个边的平方要小于另外两个边平方的和(满足一种即可)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=500+7;
struct stu{
    ll x,y;
}arr[N];
bool judge(ll x,ll y,ll z)
{
    if((arr[x].x-arr[y].x)*(arr[x].y-arr[z].y)==(arr[x].y-arr[y].y)*(arr[x].x-arr[z].x))
            return 0;
    ll xy=pow(arr[x].x-arr[y].x,2)+pow(arr[x].y-arr[y].y,2);
    ll xz=pow(arr[x].x-arr[z].x,2)+pow(arr[x].y-arr[z].y,2);
    ll yz=pow(arr[y].x-arr[z].x,2)+pow(arr[y].y-arr[z].y,2);
    if(xy+xz<yz||xy+yz<xz|| xz+yz<xy) return 1;
    else return 0;

}


int main()
{
    ll n;
    cin>>n;
    for(ll i=0;i<n;i++){
        cin>>arr[i].x>>arr[i].y;
    }
    ll ans=0;
    for(ll i=0;i<n;i++){
        for(ll j=i+1;j<n;j++){
            for(ll k=j+1;k<n;k++){
                ll a=i,b=j,c=k;
                if(judge(a,b,c)) ans++;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

E 做计数

两边同时平方可以转换为i+j+2*sqrt(i*j)=k,所以只要在小于n的数里找到可以开根号的数并保存,对每个数然后累加因子个数即可。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int arr[N];
int f(int n){
    int s=1;
    for(int i=2;i*i<=n;i++){
        if(n%i==0){
            int a=0;
            while(n%i==0){
                n/=i;
                a++;
            }
            s=s*(a+1);
        }
    }
    if(n>1) s=s*2;
    return s;
}
int main()
{
    int n;
    cin>>n;
    int sum=0;
    int pos=0;
    for(int i=1;i<=n;i++){
        int c=sqrt(i);
        if(c*c==i){
            arr[pos++]=i;
        }
    }
    for(int i=0;i<pos;i++){
        sum+=f(arr[i]);
    }
    cout<<sum<<endl;
    return 0;
}

F题

排序。主要是cmp函数

cmp(x,y)

设轮到牛牛先挑,只要x.a-y.b>y.a-x.b就可以把x放在y的前边,若轮到可乐挑,则满足x.b-y.a>y.b-x.a就可以x排在y的前边,移项发现均为x.a+x.b>y.a+y.b。所以排序后奇数为牛牛的,偶数为可乐的。

#include<bits/stdc++.h>
using namespace std;
const int N=2E5+7;
struct stu{
    int a,b,c;
}arr1[N],arr2[N];
int arr[N];
bool cmp1(const stu &x,const stu &y){
    return x.a-y.b>y.a-x.b;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>arr1[i].a;
    for(int i=1;i<=n;i++){
        cin>>arr1[i].b;
        arr1[i].c=i;
    }
    sort(arr1+1,arr1+1+n,cmp1);
    int pos=0;
    for(int i=1;i<=n;i++){
        if(i&1) {
            arr[pos++]=arr1[i].c;
        }
    }
    for(int i=0;i<pos;i++) cout<<arr[i]<<" ";
    cout<<endl;
    for(int i=1;i<=n;i++){
        if(i%2==0) cout<<arr1[i].c<<" ";
    }
    return 0;
}

G题:

这是一个让我自闭的题目,,,卡模数,我的天。一开始就是用取模写的,模数取得是1e9+7.一直不对。。卡到自闭。

最后模数取1e9+8就过了,,这他妈卡的意义何在?

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+8;
ll ksm(ll x,ll y)
{
    ll res=1;
    while(y)
    {
        if(y&1) res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}
void solve()
{

    ll a,b,c,d,e,f,g;
    cin>>a>>b>>c>>d>>e>>f>>g;
    ll x1=ksm(a,d);
    ll x2=ksm(b,e);
    ll x3=ksm(c,f);

    if((x1+x2+x3)%mod==g||(x1+x2+x3)%mod==(g+mod)%mod){
        cout<<"Yes"<<endl;
    }
    else cout<<"No"<<endl;
}


int main()
{
    ll t;
    cin>>t;
    while(t--) solve();
    return 0;
}

H施魔法

DP题目。

想想看,某一段一定是按照从小到大连续的数字。

所以先从小到大排序一下。

状态转移方程:dp[i]=min(dp[i-1]-arr[i-1]+arr[i],dp[i-k]-arr[i-k+1]+arr[i])

解释:dp[i]维护的是以i为划分点的一段长度大于等于k的子序列,那么对于i这个点,arr[i]可以做dp[i-1]的最右端,即dp[i-1]-arr[i-1]+arr[i],也可以做从i王前数k个即作为一段序列的做左端dp[i-k]-arr[i-k+1]+arr[i];

答案就是二者的最小值。。。。不太懂。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=3e5+7;
const ll INF=1e18+7;
ll dp[N];
ll arr[N];
int main()
{
    ll n,k;
    cin>>n>>k;
    for(ll i=1;i<=n;i++) cin>>arr[i];
    for(ll i=0;i<=n;i++) dp[i]=INF;
    sort(arr+1,arr+1+n);
    dp[k]=arr[k]-arr[1];
    for(ll i=k+1;i<=n;i++){
        dp[i]=min(dp[i-1]+arr[i]-arr[i-1],dp[i-k]-arr[i-k+1]+arr[i]);
    }
    cout<<dp[n]<<endl;
    return 0;
}

I题:

位运算的题目;

首先是去重,去重后有x个元素,相同元素相连,答案为0.

然后是考虑每一个位置a,当这一个位置即有0,又有1时,那么我们可将0跟1相连,答案就是pow(2,a)(x-1)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2E5+7;
ll arr[N];
map<ll,bool>mp;
ll pos=0,x,n;
bool check(ll x){
    ll a0=0;
    ll a1=0;
    for(ll i=0;i<pos;i++){
        if((arr[i]>>x)&1) a1++;
        else a0++;
    }
    if(a1!=0&&a0!=0) return 1;
    return 0;
}
int main(){
    cin>>n;
    for(ll i=1;i<=n;i++){
        cin>>x;
        if(mp[x]) continue ;
        mp[x]=1;
        arr[pos++]=x;
    }
    if(pos==1) {
        cout<<0<<endl;
        return 0;
    }
    for(ll i=0;i<=30;i++){
        if(check(i)){
            ll a=pow((ll)2,i)*(pos-1);
            cout<<a<<endl;
            return 0;
        }
    }
    cout<<0<<endl;
    return 0;
}

J题:待补

posted on 2020-02-07 22:04  Target--fly  阅读(145)  评论(0编辑  收藏  举报