2017吉首大学新生赛

http://120.78.162.102/problem.php?cid=1333&pid=0

【问题 A: 4357买糖】【等差数列】

Code:

#include <bits/stdc++.h>

using namespace std;
int main()
{
    int a,b,p,ans;

    while(cin>>a>>b>>p)
    {
        ans=0;
        ans=a+(p-1)*(b-a);
        printf("%d\n",ans);
    }
    return 0;
}
暴力

 

【问题 C: 老曹与老颜的游戏】【数论/拓展欧几里得】

Code:

#include <bits/stdc++.h>

using namespace std;
typedef long long int ll;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
   ll r=ex_gcd(b,a%b,x,y);
    ll t=x;
    x=y;
    y=t-a/b*y;
    return r;
}
bool jie(ll a,ll b,ll c,ll &x,ll &y)
{
    ll r=ex_gcd(a,b,x,y);
    if(c%r!=0) return 0;
    ll zz=c/r;
    x*=zz;
    y*=zz;
    if(x<0&&y<0) return 0;
     ll bb=b/r;
     ll aa=a/r;
    if(x<0&&y>0)
    {
        ll t=-1*x/bb;
        if(x+bb*t<0) t++;
        x=x+bb*t;
        y=y-aa*t;
        if(y>=0) return 1;
        else return 0;
    }
   else if(x>0&&y<0)
    {
        ll t=y/aa;
        if(y-aa*t<0) t--;

        x=x+bb*t;
        y=y-aa*t;
        if(x>=0) return 1;
        else return 0;
    }
    return 1;
}
ll a,b,n,x,y;
int main()
{
    while(~scanf("%lld%lld%lld",&a,&b,&n))
    {
        x=0;
        y=0;
        if(jie(a,b,n,x,y))
        {
            printf("Yes\n");
            //printf("%lld %lld\n",x,y);
        }
        else
        {
            printf("No\n");
        }
    }
    return 0;
}
拓展欧几里得

 

【问题 E: 你看见过我的小熊吗?】【最长连续合法序列】

Code:

#include <bits/stdc++.h>

using namespace std;
const int N = 1010;
int main()
{
    int t,n,a[N],len,ma;
    scanf("%d",&t);
    while(t--)
    {
        len=0;
        ma=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<n;i++)
        {
            if(a[i]==8)
            {
                len++;
                ma=max(ma,len);
            }
            else
            {
                len=0;
            }
        }
        printf("%d\n",ma);
    }
    return 0;
}
/*
10
10
8 8 8 7 6 8 8 8 8 8
6
5 8 8 2 3 4
*/
最长连续合法序列

 

【问题 H: 数的分解】【类似分拆素数和/数论】

Code:

#include<bits/stdc++.h>
using namespace std;

int is_prime(int n)
{
    for(int i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
            return 0;
    }
    return 1;
}

int main()
{
    int n,sum;
    while(~scanf("%d",&n),n)
    {
        sum=0;
        for(int i=2;i<=n/2;i++)
        {
            if(is_prime(i)&&is_prime(n-i))
                sum++;
        }
        printf("%d\n",sum);
    }
    return 0;
}
分拆素数和

 

【问题 K: 瘦瘦捡垃圾】【模拟/贪心】

Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int x,y,n,ans,sum,f;
int a[10000+10];
int cmp(int a,int b)
{
    return a>b;
}
int main()
{
    while(~scanf("%d%d",&n,&x))
    {
        ans=sum=f=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        sort(a,a+n,cmp);
        for(int i=0;i<n;i++)
        {
            sum+=a[i];
            ans++;
            if(sum>=x)
            {
                f=1;
                break;
            }
        }
        if(f) printf("%d\n",ans);
        else printf("-1\n");
    }
    return 0;
}
贪心

 

【问题 F: 是你飘了,还是我拿不动刀了】【多个STL/字符串找单词】

Code:

#include <bits/stdc++.h>

using namespace std;
vector<string> dict;
map<string,bool> mp;
int f;
int main()
{
    int cas=1;
    string s,buf;

    while (getline(cin,s))
    {
        dict.clear();
        mp.clear();
        //memset(dict,0,sizeof(dict));
        f=0;
        for(int i=0;i<s.length();i++)
            if (isalpha(s[i])){ //有单词即大小写字母标记一下
                   f=1;
            }
            else s[i]=' ';//非单词(大小写字母)用空格代替 方便后续stringstream使用
        stringstream ss(s);
        while (ss>>buf){
            //mp.clear();
            if(mp[buf]==true)
                continue;
            else
            {
                dict.push_back(buf);
                mp[buf]=true;
            }
            //cout<<"buf = "<<' '<<buf<<endl;
        }
    vector <string> ::iterator it;
    printf("Case %d:\n",cas++);
        if(f){
        for(it=dict.begin(); it!=dict.end(); it++)
                cout<<*it<<endl;
        }
        else{
            puts("NO");
        }
    }
    return 0;
}
字符串+STL

 

【问题 I: 不一样的走楼梯】【简单DP/类似“超级楼梯”】

Code:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<time.h>
#define mod 1000000009
#define ll long long
ll dp[10000+10];
ll m;
void predeal( )
{
    dp[0] = 1;//注意初始化0级
    dp[1]=1,dp[2]=2;
    for( int i=3;i<=10000;i++)
        for(int j=1;j<=i;j++)
           dp[i] = (dp[i]%mod + dp[i-j]%mod)%mod;//一边取模,否则炸
}
int main()
{
    predeal( );
    while(~scanf("%lld",&m))
    {
        printf("%lld\n",dp[m]%mod);
    }
    return 0;
}
DP

 

【问题 B: 周老师的区间问题】【将一些连在一起的区间合并在一起,最后从小到大输出每个合并后的区间

【分析】:既然要从小到大,那第一步自然是将每个区间以起点为关键字从小到大排序,然后从第二个区间开始,每个区间与前一个选的区间进行比较,若连在一起,则合并区间,否则,新开一个区间,将这个区间存入新开的区间。注意:除了判断是否连在一起,还要判断终点的大小,如果终点大一些才存,否则无视该区间。

Code:

#include<bits/stdc++.h>

using namespace std;

struct node
{
    int a,b;
}a[50005];

int n,tot=0;
int q[50005],p[50005];
bool cmp(const node &a,const node &b)
{
    if(a.a!=b.a) return a.a<b.a;
    return a.b<b.b;
}
void ef(int i)
{
    int l=1,r=tot;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(a[i].a>p[mid]) l=mid+1;
        if(a[i].a<=p[mid]) r=mid;
    }
    if(a[i].b>p[l]) p[l]=a[i].b;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].a,&a[i].b);
    }
    sort(a+1,a+n+1,cmp);
    q[++tot]=a[1].a;
    p[tot]=a[1].b;
    for(int i=2;i<=n;i++)
    {
        if(a[i].a<=p[tot])
            ef(i);
        else
        {
            q[++tot]=a[i].a;
            p[tot]=a[i].b;
        }
    }
    printf("%d\n",tot);
    for(int i=1;i<=tot;i++)
    {
        printf("%d %d\n",q[i],p[i]);
    }
}
区间贪心

 

【问题 J: Jack的宝物问题】【*技巧枚举/DP】

Code:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<time.h>
#define mod 609929123
#define ll long long
ll n,a[20000+100],sum[20000+100];
ll ans;
int main()
{
    scanf("%lld",&n);
    sum[0]=0;
    for(ll i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    ans=0;
    for(ll i=1; i<=n; i++)
    {
        for(ll j=i+1; j<=n; j++)
        {
            ans += ( a[i] * a[j]* ( sum[n]-sum[j] )%mod )%mod;
            //printf("ans = %d\n",ans);
        }
    }
    printf("%lld\n",ans % mod);
}
枚举/DP

 

【问题 G: 三角填阵】【模拟填数】

Code:

#include<bits/stdc++.h>

using namespace std;

char a[105][105];
char d[4]={ '+','-','*','/' };

int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int flag=0;
        int x=0;
        
        for(int i=0; i<n; i++)
        {
            if(x%2==0)
            {
                for(int j=i; j<n; j++)
                {
                    a[j][j-i]=d[flag%4];
                    flag++;
                }
            }
            else
            {
                for(int j=n-1; j>=i; j--)
                {
                    a[j][j-i]=d[flag%4];
                    flag++;
                }
            }
            x++;
        }
        
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(j<=i)
                    printf("%c%c",a[i][j],j==i?'\n':' ');
            }
        }
        
        printf("\n");
        
    }
}
模拟

 

posted @ 2017-12-25 01:48  Roni_i  阅读(283)  评论(0编辑  收藏  举报