第二届中国计量大学ACM程序设计竞赛个人赛(同步赛)

第二届中国计量大学ACM程序设计竞赛个人赛(同步赛)

A Little Gyro and Sort
快读加快排

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int a[10005];
int main(void)
{
    int t;scanf("%d",&t);
    while(t--){
        int n;scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        sort(a,a+n);
        for(int i=0;i<n-1;i++){
            printf("%d ",a[i]);
        }
        printf("%d\n",a[n-1]);
    }
    return 0;
}

B Little Gyro and Sets
不是m的倍数总和 减去 是m的倍数 的和

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;

int main(void)
{
    int t;cin>>t;
    while(t--){
        ll a,b;cin>>a>>b;
        ll c=b/a;//A=(1+c)*c/2*a
        cout<<(1+b)*b/2-(1+c)*c*a<<endl;
    }
    return 0;
}

C Little Gyro and Numbers
p^q 和 q^p的比较,曾经一道比较难思考的高考题

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int read()
{
    int c=0;
    char s;
    while((s=getchar())>'9'||s<'0');
    c=s-'0';
    while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
    return c;
}
int a[100005],b[100005];//a用来按顺序输出的,b用来排序
int main(void)
{
    int m;m=read();
    for(int k=1;k<=m;k++){
        int n;cin>>n;
        for(int i=0;i<n;i++){
            a[i]=read();
            //以下处理使3的数排列后变成了首位
            if(a[i]==2)//为什么?当p为2时,只有q大于4时才能情况++
                a[i]=4;//而b中的2变成了4没有影响
                //巧妙的是,3^2>2^3,所以,2变成4是很巧妙的
            if(a[i]==1)//1和任何的数相比都不能情况++,所有放在最后了
                a[i]=inf;
            b[i]=a[i];
        }
        sort(b,b+n);
        cout<<"Case "<<k<<":"<<endl;
        for(int i=0;i<n;i++)//找到第一个比a【i】大的数,并返回下标。
            printf("%d\n",n-(upper_bound(b,b+n,a[i])-b));
    }
    return 0;
}

D Little Gyro and Array
用树状数组维护差分数组可以过
搞了我一天多,一个渣渣学了好多东西。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
typedef long long ll;
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
ll read()
{
    ll c=0;int flag=1;
    char s;
    while((s=getchar())>'9'||s<'0')if(s=='-')flag=-1;
    c=s-'0';
    while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
    return c*flag;
}
ll n,m;
ll a[100005];
ll t1[100005];
ll t2[100005];
void add(int L, int R, ll x, ll y)
{
    for(int i=L;i<=n;i+=i&-i){t1[i]+=x; t2[i]+=y;}
    for(int i=R+1;i<=n;i+=i&-i){t1[i]-=x; t2[i]-=y;}
}
ll ask(int p)
{
    ll x=0, y=0;
    for(int i=p;i;i-=i&-i){x+=t1[i]; y+=t2[i];}
    return x + p*y;
}
int main(void)
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    while(m--){
        int q;cin>>q;
        if(q==1){
            int l,r,k,d;cin>>l>>r>>k>>d;
            //b[l]+=k;b[r+1]-=k+(r-l)*d;  即区间(l+1,r)值加(r-l)*d
            add(l,r,k-d*l,d);
        }
        else{
            int q;cin>>q;
            cout<<a[q]+ask(q)<<endl;
        }
    }
    return 0;
}

E Little Gyro and Derrick
得走到哪就拦到哪,边角是主要点

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int read()
{
    int c=0;int flag=1;
    char s;
    while((s=getchar())>'9'||s<'0')if(c=='-')flag=-1;
    c=s-'0';
    while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
    return c*flag;
}

int main(void)
{
    int t;cin>>t;
    while(t--){
        int n,m,k;cin>>n>>m>>k;
        int temp=0;
        while(k--){
            int x,y;cin>>x>>y;
            if(x<=5||x>=n-4||y<=5||y>=m-4)temp=1;
            //为什么是5,自己模拟一下就可以得出至少把它封4步
            //如果大于5,就先把4个角各先封了一边
        }
        if(temp) cout<<"Happy Little Gyro\n";
        else cout<<"Sad Little Gyro\n";
    }
    return 0;
}

F Little Gyro and Sequences
问题问得很巧妙,第一问是最大上升不能等值的
而第二问是可以转化为为问最大下降能等值,具体搞几个实例就可以模拟一下了
这里用了O(nlogn)的算法。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int a[200005];
int b[200005];
int read()
{
    int c=0;
    char s;
    while((s=getchar())>'9'||s<'0');
    c=s-'0';
    while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
    return c;
}
int main(void)
{
    int n;cin>>n;
    for(int i=0;i<n;i++){
        a[i]=read();
    }
    int len=0;//新数组的长度
    b[0]=a[0];
    for(int i=1;i<n;i++){
        if(b[len]<a[i]){
            len++;
            b[len]=a[i];
        }
        else{
            //二分查找,将从左到右边数第 1 个大于 'temp' 的数字更新为 6
            int l=0,r=len;
            int temp=a[i];
            while(l<r){
                int mid=(l+r)/2;
                if(b[mid]<temp) l=mid+1;
                else r=mid;
            }
            b[r]=temp;
        }
    }
    int up=len;
    memset(b,0,sizeof b);
    len=0;

    b[0]=a[0];
    for(int i=1;i<n;i++){
        if(b[len]>=a[i]){
            len++;
            b[len]=a[i];
        }
        else{
            //二分查找
            int l=0,r=len;
            int temp=a[i];
            while(l<r){
                int mid=(l+r)/2;
                if(b[mid]>=temp) l=mid+1;
                else r=mid;
            }
            b[r]=temp;
        }
    }
    cout<<up+1<<" "<<len+1;
    return 0;
}

G Disk Scheduling
不是要求你想的那个最优算法,而是按着它给你的方法求,就是指针头要往最小的那个方向来回跑。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int a[1000005];
int read()
{
    int c=0;
    char s;
    while((s=getchar())>'9'||s<'0');
    c=s-'0';
    while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
    return c;
}
int main(void)
{
    int n,m;cin>>n>>m;
    for(int i=1;i<=n;i++){
        a[i]=read();
    }
    sort(a+1,a+1+n);
    //for(int i=1;i<=n;i++)cout<<a[i]<<" ";
    int l=1,r=n;//指针
    for(int i=1;i<n;i++){
        if(a[i]<=m&&a[i+1]>=m){
            l=r=i;break;
        }
    }
    r++;//走一步
    ll num=0;
    while(l>0||r<=n){
        //cout<<l<<" "<<r<<endl;
        if((r!=n+1&&a[r]-m<m-a[l])||l==0){
            num+=a[r]-m;
            m=a[r];
            r++;
        }
        else{
            num+=m-a[l];
            m=a[l];
            l--;
        }
    }
    cout<<num;
    return 0;
}

H Monster Fighting
打怪要耗血,但是打完可以补血
根据这只怪是可以补血还是耗血先给分类,然后把可以补的重小到大先补了,再把耗血的重大到小打了,一有不行的就不行了。

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int read()
{
    int c=0;int flag=1;
    char s;
    while((s=getchar())>'9'||s<'0')if(s=='-')flag=-1;
    c=s-'0';
    while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
    return c*flag;
}
struct node
{
    int l,r;
}a[100005],b[100005];
bool cmp(node aa,node bb)
{
    return aa.l<bb.l;
}
int main(void)
{
    int t;t=read();
    while(t--){
        ll n,m;n=read(),m=read();
        int a1=0,a2=0;
        int x,y;
        for(int i=1;i<=n;i++){
            x=read(),y=read();
            if(x<=y) a[++a1].l=x,a[a1].r=y-x;
            else b[++a2].l=x,b[a2].r=y-x;
        }
        sort(a+1,a+1+a1,cmp);
        sort(b+1,b+1+a2,cmp);
        int temp=1;
        for(int i=1;i<=a1;i++)//把可以补血的给先吃了
            if(m>a[i].l) m+=a[i].r;
            else{temp=0;break;}
        for(int i=a2;i>=1;i--){//先打耗血最多的
            if(m>b[i].l) m+=b[i].r;
            else{temp=0;break;}
        }
        printf(temp?"Yes\n":"No\n");
    }
    return 0;
}

I Logs Stacking
很神奇的一道题,最后变成了求斐波那契数列的后4位,而后4为在15000这里是一个循环点,要验证的话跑一遍就知道了

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int a[15005];
int main(void)
{
    a[1]=1;
    for(int i=2;i<=15001;i++){
        a[i]=a[i-1]+a[i-2];
        a[i]%=10000;
    }
    int t;cin>>t;
    while(t--){
        int k;cin>>k;
        cout<<a[k%15000]<<endl;
    }
    return 0;
}

L Story of Eden
刚开始被英语吓到了

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
 
int main(void)
{
    int t;cin>>t;
    while(t--){
        string s;
        cin>>s;
        cout<<"Love replied to "<<s<<", \"Nothing is good or bad, and the interpretation is in people.\""<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值