集训队日常训练20180518-DIV2

A.3232

n个物品,换取要花积分,问刚好花完积分能换最大多少价值的物品。

多重背包。

#include <bits/stdc++.h>
using namespace std;
int t[1005];
int main()
{
    int m,n,i,a,b,c,T,j,k;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&m,&n);
        memset(t,0,sizeof(t));
        for(k=0;k<n;k++)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(t[c]<a)
                t[c]=a;
            for(i=0;i<=b;i++)
            {
                for(j=m;j>=c;j--)
                {
                    if(j-c*i>=0&&t[j-c*i]&&t[j-c*i]+a*i>t[j])
                        t[j]=t[j-c*i]+a*i;
                }
            }

        }
        if(t[m]) printf("The maximum value is %d.\n",t[m]);
        else printf("This is impossible.\n");
    }
    return 0;
}
A.cpp

B.3196

医生优先处理级别最高的病人,给n件发生的事,对于每个OUT输出。

优先队列。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
struct node
{
    int a, b;
    friend bool operator<(node a, node b)
    {
        if(a.a != b.a) return a.a < b.a;
        return a.b > b.b;
    }
};
int main()
{
    int n;
    while(cin >> n)
    {
        priority_queue<node> qu[4];
        string str;
        int cnt = 0;
        for(int i = 1; i<= n; i++)
        {
            cin >>str;
            if(str == "IN")
            {
                int a,b; cin >> a >> b;
                qu[a].push({b,++cnt});
            }
            else if(str == "OUT")
            {
                int a; cin >> a;
                if(!qu[a].empty()) cout <<qu[a].top().b << endl, qu[a].pop();
                else cout << "EMPTY\n";
            }
        }
    }
    return 0;
}
B.cpp

C.4705

给一个数字串问取出一个连续的若干位能组成的最大素数。

暴力。

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

int main()
{
    string str;
    while(cin >>str)
    {
        int maxx = -1;
        for(int i = 0; i < str.size(); i++)
        {
            int temp = 0;
            for(int j = i; j < str.size(); j++)
            {
                temp = temp*10 + str[j]-'0';
                int f = 0;
                for(int k = 2; k <= sqrt(temp); k++)
                {
                    if(temp % k == 0) {f = 1; break;}
                }
                if(temp != 1 && !f) maxx = max(maxx,temp);
            }
        }
        if(maxx == -1) cout << "None\n";
        else cout << maxx <<endl;
    }
    return 0;
}
C.cpp

D.3293

给一个数A,一个数B,问AB的二进制中有几个数不同。

taozi的暴力。

#include<stdio.h>
int main()
{
    __int64 a,b;
    while(scanf("%I64d%I64d",&a,&b)!=EOF,a||b)
    {
        int c[65]={0},d[65]={0};
        int c1=64,d1=64;
        while(a)
        {
            c[c1--]=a%2;
            a/=2;
        }
        while(b)
        {
            d[d1--]=b%2;
            b/=2;
        }
        int ans=0;
        for(int i=0;i<=64;i++)
            if(c[i]!=d[i])
                ans++;
        printf("%d\n",ans);
    }
    return 0;
}
D.cpp O(64)

zenghuan_的位运算。

1. A & B,得到的结果C中的1的位表明了A和B中相同的位都是1的位;
2. A | B, 得到的结果D中的1的位表明了A和B在该位至少有一个为1的位,包含了A 与 B 都是1的位数,
经过前两步的位运算,,C 中1的位表明了A 和 B在该位都是1,D中为0的位表明了A 和 B 在该位都是0 ,所以进行第三步。
3. C ^ D,E 中为1的位表明了A 和 B不同的位。

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

int main()
{
    long long a,b,c,d,e;
    while(cin>>a>>b)
    {
        if(a==0&&b==0)break;
        c=a&b;
        d=a|b;
        e=a^b;
        long long sum=0;
        while(e!=0)
        {
            e=((e-1)&e);
            sum++;
        }
        cout<<sum<<endl;
    }
    return 0;
}
D.cpp O(64/8)

E.2938

m*n的矩阵,绕圈填。

模拟。

#include <bits/stdc++.h>
using namespace std;
int number;
int n,m,jishu;
char arr[55][55];
int main()
{
    cin>>n>>m;
    char s='A';
    int t=n/2+n%2;
        for(int i=0;i<t;i++){
            for(int j=i;j<=m-i-1&&jishu<n*m;j++){
                arr[i][j]=s++;
                jishu++;
                if(s=='Z'+1) s='A';
            }
            for(int j=i+1;j<=n-i-1&&jishu<n*m;j++){
                arr[j][m-i-1]=s++;
                jishu++;
                if(s=='Z'+1) s='A';
            }
            for(int j=m-i-2;j>=i&&jishu<n*m;j--){
                arr[n-i-1][j]=s++;
                jishu++;
                if(s=='Z'+1) s='A';
            }
            for(int j=n-i-2;j>=i+1&&jishu<n*m;j--){
                arr[j][i]=s++;
                jishu++;
                if(s=='Z'+1) s='A';
            }
        }
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            cout << "   " << arr[i][j];
            if(j==m-1) cout << endl;
        }
        return 0;
}
E.cpp

F.2763

求(0! + 1! + 2! + 3! + 4! + ... + n!)%m。

思维,首先n>m的部分都是0,1!%m和2!%m那么根据乘法的同余2!=1%m*2%m。

#include<stdio.h>
#define ll __int64
int main()
{
    int t;
    char n[105];
    scanf("%d",&t);
    while(t--)
    {
        ll N=0,M;
        scanf("%s%I64d",n,&M);
        for(int i=0;n[i];i++)
        {
            if(N>=M){N=M;break;}
            N=N*10+n[i]-'0';
        }
        ll ans=1,sum=1;
        for(int i=1;i<=N;i++)
            sum=(sum+ans*i%M)%M,ans=ans*i%M;
        printf("%I64d\n",sum%M);
    }
    return 0;
}
F.cpp

G.4764

一个n×n的正方形,现在你在正方形的左下角,每次你可以顺时针走n+1单元的距离,求多少次之后你可以回到起点。

找规律。

#include<stdio.h>
int main(){
    __int64 n,s;
    while(scanf("%I64d",&n)!=EOF){
        if(n%2){
            if((n+1)%4) s=2*n+1;
            else s=n+1;
        }
        else s=4*n+1;
        printf("%I64d\n",s);
    }
    return 0;
}
G.cpp

H.4781

ax3+bx2+cx+d=0 ,给出(a,b,c,d)求x。

暴力,由于根的范围很小,并且保留两位小数。注意在比较double会有误差,要取fabs<=1e-5。

#include<stdio.h>
#include<math.h>
int main(){
    float a,b,c,d;
    scanf("%f%f%f%f",&a,&b,&c,&d);
    int i,f=1;
    for(i=-10000;i<=10000;i++){
        float x=i*1.0/100;
        if(fabs(a*x*x*x+b*x*x+c*x+d)<=1e-5){
            if(f){
                printf("%.2f",x);f=0;
            }
            else printf(" %.2f",x);
        }
    }
    printf("\n");
}
H.cpp

I.2955

n个点m条无向边,问至少加多少条边使得全图连通。

并查集模板题。

#include<bits/stdc++.h>
using namespace std;
int F[101],T;
int Find(int x)
{
    return F[x]==x? x:Find(F[x]);
}
int main(){
    int N,M,A,B;
    while(cin>>N>>M)
    {
        for(int i=1;i<=N;i++)
            F[i]=i;
        T=N-1;
        for(int i=0;i<M;i++)
        {
            cin>>A>>B;
            int x=Find(A);
            int y=Find(B);
            if(x!=y)
            {
                F[x]=y;
                T--;
            }
        }
        cout<<T<<endl;
    }
}
I.cpp

J.3207

n个点m条无向边,问C到D的最短路。

floyd最短路模板题,这里用dijstra也行。

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

int n,m,ss[1005][1005];
void dij(int a,int b)
{
    int dis[n+1][n+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            dis[i][j]=ss[i][j];
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            if(dis[i][j]>dis[k][j]+dis[i][k])
            dis[i][j]=dis[k][j]+dis[i][k];
    if(dis[a][b]==0x3f3f3f3f)cout<<"NO"<<endl;
    else cout<<dis[a][b]<<endl;
}
int main()
{
    int a,b,c;
    cin>>n>>m;
    memset(ss,0x3f,sizeof(ss));
    for(int i=0;i<m;i++)
    {
        cin>>a>>b>>c;
        ss[a][b]=ss[b][a]=c;
    }
    while(cin>>a>>b)
    {
        if(a==0&&b==0)break;
        dij(a,b);
    }
    return 0;
}
J.cpp

猜你喜欢

转载自www.cnblogs.com/taozi1115402474/p/10886969.html