省赛训练赛1

题目链接:http://acm.ocrosoft.com/contest.php?cid=1034


A:水题啊,这个数据范围直接暴力都没事的。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
    int n,m;
    int x,y;
    int s[10010];
    while(cin>>n>>m)
    {
        memset(s,0,sizeof(s));
        for(int i=0;i<m;i++)
        {
            cin>>x>>y;
            for(int j=x;j<=y;j++)
                s[j]=1;
        }
        int res=0;
        for(int i=0;i<=n;i++)
        {
            if(!s[i])
                res++;
        }
        cout<<res<<endl;
    }
    return 0;
}


B:01背包

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
    int t,m;
    int s[1010];
    int w[1010];
    int dp[1010];
    while(cin>>t>>m)
    {
        memset(dp,0,sizeof(dp));
        for(int i=0;i<m;i++)
        {
            cin>>s[i];
            cin>>w[i];
        }
        for(int i=0;i<m;i++)
        {
            for(int j=t;j>=s[i];j--)
                dp[j]=max(dp[j],dp[j-s[i]]+w[i]);
        }
        cout<<dp[t]<<endl;
    }
    return 0;
}

C:暴力找循环节 

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int L=110000;
int l[11]={1,1,4,4,2,1,1,4,4,2};
int k;
void multiplyh(int x[], int y[], int z[]) {//高精度高乘
    int up = 0;
    for (int ii = 1; ii <= k; ii++) {
        for (int j = 1; j <= k; j++)
        {
            z[ii + j - 1] += (x[j] * y[ii] + up) % 10;
            up = (x[j] * y[ii] + up) / 10;
        }
        up = 0;
    }
    for (int ii = 1; ii <= k; ii++) {//进位
        z[ii + 1] += z[ii] / 10;
        z[ii] %= 10;
    }
}
void multiplyl(int x[], int yy, int z[]) {//高精度低乘
    int up = 0;
    for (int ii = 1; ii <= k; ii++) {
        z[ii] = (x[ii] * yy + up) % 10;
        up = (x[ii] * yy + up) / 10;
    }
}
int main()
{
    string a;
    int b[205],c[205],d[205],now[205],last[205],ss[205];
     memset(last, 0, sizeof last);
    memset(b, 0, sizeof b); memset(now, 0, sizeof now);
    memset(d, 0, sizeof d); memset(c, 0, sizeof c); memset(ss, 0, sizeof ss);
    cin>>a;
    cin>>k;
    int n=a.size();
    int z=0;
    for(int i=n-1;i>=n-k;i--)
        c[++z]=a[i]-'0';
    for(int i=1;i<=k;i++)
        b[i]=c[i];
    for(int i=1;i<l[c[1]];i++)
    {
        memset(d,0,sizeof(d));
        multiplyh(b,c,d);
        for(int j=1;j<=k;j++)b[j]=d[j];
    }
    ss[1]=l[c[1]];
    for(int i=1;i<=k;i++)now[i]=b[i];
    for(int i=1;i<=k;i++)last[i]=now[i];
    int pos=2;
    int t=0;
    while(pos<=k)
    {
        for(int i=1;i<=k;i++)
        {
            b[i]=c[i];
        }
        t=0;
        while(t<11)
        {
            t++;
            memset(d,0,sizeof(d));
            multiplyh(b,now,d);
            for(int j=1;j<=k;j++)
            {
                b[j]=d[j];
            }
            if(b[pos]==c[pos])
            {
                break;
            }
            memset(d,0,sizeof(d));
            multiplyh(last,now,d);
            for(int j=1;j<=k;j++)
            {
                last[j]=d[j];
            }
        }
        if(t>=11){cout<<-1<<endl;return 0;}
        for(int j=1;j<=k;j++)now[j]=last[j];
        memset(d,0,sizeof(d));
        multiplyl(ss,t,d);
        for (int i = 1; i <= 100; i++)  ss[i] = d[i];
        pos++;
    }
    int flag = 0;
    for (int i = 100; i >= 1; i--) {
        if (ss[i]) flag = 1;
        if (flag) cout << ss[i];
    }
    cout<<endl;
    return 0;
}


D:数学题,由题意可知该数由两个质数组成,由于质数不能再分所以该数一共有四个因子,1和它本身以及两个质数因子。直接从该数的平方根开始遍历找到较小因子,除一下就是最大因子 

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
    int n;
    while(cin>>n)
    {
        for(int i=sqrt(n*1.0);i>1;i--)
        {
            if(n%i==0)
                cout<<n/i<<endl;
        }
    }
    return 0;
}


E:模拟一下就好了,这道题只要看懂题意就没什么难度。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct node
{
    int name;
    int num;
    bool flag;
}s[10010][110];
int main()
{
    int n,m;
    int x,y;
    int cmp[10010];
    while(cin>>n>>m)
    {
        memset(cmp,0,sizeof(cmp));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d%d",&x,&y);
                s[i][j].name=j;
                s[i][j].num=y;
                if(x)
                    s[i][j].flag=1,cmp[i]++;
            }
        }
        cin>>x;
        int cx=0;
        int res=0;
        while(cx<n)
        {
            int cnt=s[cx][x].num;
            (res+=cnt)%=20123;
            int cntt=(cnt-1)%cmp[cx]+1;
            for(int i=0;i<=m*cnt;i++)
            {
                if(s[cx][(x+i)%m].flag)
                    cntt--;
                if(!cntt)
                {
                    x=(x+i)%m;
                    break;
                }
            }
            cx++;
        }
        cout<<res<<endl;
    }
    return 0;
}


F:动态规划,dp[i][j]代表前i种花里面取j盆有几种方案。初始化确定之后就没什么难点了。

#include<cmath>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int n, m;
    int a[110];
    int dp[110][110];
    while (cin >> n >> m)
    {
        memset(dp, 0, sizeof(dp));
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        for (int i = 0; i <= a[1]; i++)
            dp[1][i] = 1;
        for (int i = 0; i <=n; i++)
            dp[i][0] = 1;
        for (int i = 2; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                for (int k = 0; k <= a[i] && j >= k; k++)
                {
                    (dp[i][j] += dp[i - 1][j - k]) %= 1000007;
                }
            }
        }
        cout << dp[n][m] << endl;
    }
    return 0;
}


G:SPFA做一下然后判断一下就可以了,数据很水的

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
int a[105][105];
int c[105];
int dis[105][105];
const int inf=0x3f3f3f3f;
int main()
{
    int n,k,m,s,t;
    while(~scanf("%d%d%d%d%d",&n,&k,&m,&s,&t))
    {
        int i,j;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(i==j)
                dis[i][j]=0;
                else dis[i][j]=inf;
            }
        }
        for(i=1;i<=n;i++)
        {
            scanf("%d",&c[i]);
        }
        for(i=1;i<=k;i++)
        {
            for(j=1;j<=k;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        int u,v,w;
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            dis[u][v]=w;
            dis[v][u]=w;
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(a[c[j]][c[i]]==1)
                    dis[i][j]=inf;
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                for(int k=1;k<=n;k++)
                {
                    dis[j][k]=min(dis[j][k],dis[j][i]+dis[i][k]);
                }
            }
        }
        if(dis[s][t]<inf)
        {
            printf("%d\n",dis[s][t]);
        }
        else printf("-1\n");
    }
    return 0;
}


H:数据范围只有2^6,直接暴力就好了

#include<cmath>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int n;
    bool s[66][66];
    bool vis[66];
    while (cin >> n)
    {
        memset(s, 0, sizeof(s));
        for (int i = 1; i < 1 << n; i++)
        {
            int p = 0;
            printf("<%d>", i);
            memset(vis, 0, sizeof(vis));
            for (int j = 1; j <= 1 << n; j++)
            {
                if (vis[j])
                    continue;
                vis[j] = 1;
                for (int k = j + 1; k <= 1 << n; k++)
                {
                    if (!s[j][k] && !vis[k])
                    {
                        s[j][k] = 1;
                        vis[k] = 1;
                        if (p++)
                            cout << ",";
                        cout << j << "-" << k;
                        break;
                    }
                }
            }
            cout << endl;
        }
    }
    return 0;
}


J:直接模拟一下就好了,由于乘客只可能越来越多,所以第二站下车人数在0~m之间,暴力就能过

#include<cmath>
#include<cstdio>
#include<vector>
#include<iomanip>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long int 
LL up[10000];
LL down[10000];
LL ck[10000];
int main()
{
    LL a, n, m, x; 
    while (~scanf("%ld %ld %ld %ld", &a, &n, &m, &x))
    {
        memset(ck, 0, sizeof(ck));
        up[1] = a;
        down[1] = 0;
        ck[1] = a;
        bool flag = 0;
        for (LL i = 0; i <= m; i++)
        {
            up[2] = i;
            down[2] = i;
            ck[2] = ck[1];
            for (LL j = 3; j<n; j++)
            {
                up[j] = up[j - 1] + up[j - 2];
                down[j] = up[j - 1];
                ck[j] = ck[j - 1] + up[j - 2];
            }
            if (ck[n - 1] == m)
            {
                printf("%ld\n", ck[x]); 
                flag = 1; 
                break;
            }
        }
        if (!flag)
            printf("No answer.\n");
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/b_r_e_a_d/article/details/79597361
今日推荐