重新ACM,牛客网ACM多校训练第五场

中途因为很多原因,本来已经不打算比了。但是还是很不愿放下啊。就算是最后一点机会还是要好好把握的。

虽然已经没有队友了。不过一个人也可以勉强试试嘛。

很久没有写题了。这次只写出了三题。https://www.nowcoder.com/acm/contest/143#question。很是尴尬。

A题,

大概意思就是:给你N个成绩对应N个学分,一个公式。删k个成绩后,学分绩最高。怎么删。

A题是一个标准的01规划问题。

用二分的思想很容易的。但是我当时看错题目了。这题我交了10次,我一只在想为什么。特么的。

#include<bits/stdc++.h> 
#define INF 1e9
#define eps 0.000001
using namespace std;
typedef long long ll;
 
const ll _max =  1e5+50;
struct node{
    double x,y,s;
}a[_max];
bool cmp(node n1,node n2){
    return n1.s>n2.s;
}
int main(){
    ll n,k;
    while(cin>>n>>k){
        for(int i=1;i<=n;i++) cin>>a[i].x;
        for(int i=1;i<=n;i++) cin>>a[i].y;
        for(int i=1;i<=n;i++) a[i].y*=a[i].x;
        double l,r,mid;
        l=0.0; r=1000.0;
        while(r-l>eps){
            double sum=0.0;
            mid=(l+r)/2;
            for(int i=1;i<=n;i++)
                a[i].s=a[i].y-mid*a[i].x;
            sort(a+1,a+n+1,cmp);
            for(int i=1;i<=n-k;i++){
                sum+=a[i].s;
            }
            if(sum>0)
                l=mid;
            else
                r=mid;
        }
        cout<<fixed<<setprecision(11)<<mid<<endl;
    }
    return 0;
}

G题

G题大概意思就是:给两个整数n,c。要求你再1-n中找到两个数a,b。使得gcd(a,b)== c。并且a*b最大。

这题目其实我觉得不牵扯太多算法。完全就是一个思维题了。

注意a是可以等于b的。

所以gcd(c,c)=c是一定的。所以只有当n<c的时候才会没有结果输出-1.

gcd(a,b) = c 。 说明一定包括公因数有且只有c。

可以计做: a = c*x1, b = c*x2.

因为只有公因数c,那么x1,x2互质。因为a*b=c*c*x1*x2要尽量大。

所以x1*x2 = (n/c)*(n/c-1)   (连续的两个数互质)。

忘了判定n和c的大小错了8次。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
const ll _max =  1e9+50;
int main(){
    ll c,n;
    while(cin>>c>>n){
        if(n < c){
            cout<<-1<<endl;
            continue;
        }
        ll a = n/c;
        if(a == 1) cout<<c*c<<endl;
        else cout<<c*c*a*(a-1)<<endl;
    }
    return 0;
}

J题

这题我感觉没啥说的。其实枚举下情况就好了。这是我唯一一道没有脑残的题目。

直接放代码,就不说啥了。哦,对了。范围一看就用了大数。

#include<bits/stdc++.h>
#define INF 1e9
#define eps 0.000001
using namespace std;
typedef long long ll;
string mul(ll n,ll t){
    string x;
    while(n){
        x += ('0'+n%10);
        n/=10;
    }
    ll arr[2000];
    memset(arr,0,sizeof(arr));
    int l = x.length();
    for(int i = 0 ; i < l ; i++){
        arr[i]= x[i]-'0';
        arr[i]*=t;
    }
    for(int i = 0 ; i < l ; i++){
        arr[i+1]+=arr[i]/10;
        arr[i]=arr[i]%10;  
    }
    int ch = arr[l];
    while(ch){
        arr[l++]=ch%10;
        ch/=10;
    }
    string ret = string(l,'0');
    for(int i = 0 ; i < l ; i++)
        ret[i]+=arr[i];
    reverse(ret.begin(),ret.end());
    for(int i = 0 ; i < l ; i++){
        if(ret[i] != '0'){
            ret=ret.substr(i);
            break;
        }
    }
    return ret;
}
string add(string s1,string s2){ 
    int arr1[5000],arr2[5000],arr3[5000];
    memset(arr1,0,sizeof(arr1));
    memset(arr2,0,sizeof(arr2));
    memset(arr3,0,sizeof(arr3));
    reverse(s1.begin(),s1.end());
    reverse(s2.begin(),s2.end());
    int len = max(s1.length(),s2.length());
    for(int i = 0 ; i < s1.length() ; i++)
        arr1[i] += s1[i]-'0';
    for(int i = 0 ; i < s2.length() ; i++)
        arr2[i] += s2[i]-'0';
    for(int i = 0 ; i < len ; i++)
        arr3[i] += arr1[i] + arr2[i];
    string ret =string(len+1,'0');
    for(int i = 0 ; i < len+1 ; i++){
        arr3[i+1] += arr3[i]/10;
        arr3[i] %= 10;
        ret[i] += arr3[i];
    }
    reverse(ret.begin(),ret.end());
    for(int i = 0 ; i < len+1 ; i++)
        if(ret[i] != '0'){
            ret = ret.substr(i);
            break;
        }
    if (ret==string(len+1,'0')) ret="0";
    return ret;
}
 int main(){
    ll n,p2,p3;
    while(cin>>n>>p2>>p3){
        string ans;
        double np2 = p2/2.0;
        double np3 = p3/3.0;
        if(np3 > np2){ // 3 daijia >2
            ll n1 = n/2;
            ll n2 = n%2;
            if(n2 == 1){ // sheng 1
                if(p3-p2 < p2){ // -p2 + p3  < p2
                    n1--;
                    n2 = 1;
                    ans = add(mul(p2,n1),mul(p3,n2));  
                }
                else{
                    n1++;
                    ans = mul(p2,n1);
                }
            }
            else ans = mul(p2,n1); // gang hao an pai
        }
        else{// 2 dai jia > 3
            ll n1 = n/3;
            ll n2 = n%3;
            if(n2 == 2){//sheng 2
                if(p2 < p3){// 2ren fang hua suan
                    n2 = 1;
                    ans = add(mul(p3,n1),mul(p2,n2));
                }
                else{//3 ren fang hua suan
                    n1++;
                    ans = mul(p3,n1);  
                }
            }
            else if(n2 == 1){//sheng 1
                if(p2 < p3){//2 hao fang pian yi
                    if(p2 < p2*2-p3){//2 hao fang zhi jie kai
                        n2 = 1;
                        ans = add(mul(p3,n1),mul(p2,n2));
                    }
                    else{//tui 3 ren kai liang 2 ren
                        n1--;
                        n2 = 2;
                        ans = add(mul(p3,n1),mul(p2,n2));
                    }
                }
                else{//3 hao fang pian yi
                    n1++;
                    ans = mul(p3,n1);
                }
            }
            else{//ren gang hao
                ans = mul(p3,n1);
            }  
        }
        cout<<ans<<endl;
    }
    return 0;
 }

补题:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值