第十九届浙大校赛

目录

A Thanks, TuSimple!

B Even Number Theory

C Robot CleanerI

E Potion

G Postman

J  Extended Twin Composite Number


A Thanks, TuSimple!

【题意】有n个女生,m个男生;分别读入各自的身高,然后读入1/0(要与比他高/低的人跳舞),问最多可以配对多少人

【分析】

分成4个区域: 要找比他高的男生,要找比他低的男生

                         要找比它高的女生,要找比她低的女生

4个区域排序,然后交叉求解即可

【代码】

#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long ll;
const int maxn=1e5+10;
ll a[maxn],b[maxn];
vectora1,b1,a2,b2;
ll n,m;

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        ll n,m;scanf("%lld%lld",&n,&m);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=0;i

B Even Number Theory

【题意】定义一个集合E,集合里的数都是偶数;定义e-prime表示集合E里的偶数并且满足不存在两个不同的偶数a,b使得a×b=这个数;

定义P序列,序列里的数都是e-prime

定义e!! ,公式见题,注意这里k只需要是偶数就好,然后求可以分成的最长的长度

【分析】可以发现,2^n 的长度是2^n-1,然后迭代;

比如n=16, ans=15;n=20, ans=ans(16)+ans(20-16)=2^4-1+2^2-1=15+3=18

【代码】C++高精度...  注意细节处理比如memset的初始化问题和A B C数组运算时的赋值问题

#include
using namespace std;

const int maxn=1e3+10;
int A[maxn],B[maxn],C[maxn];

///除法
string div(string a,int b)
{
    if(a=="0")return a;
    int len=a.length();
    string ans;
    int d=0;
    for(int i=0;i>s;
        s=div(s,2);
        int k=1;
        string ans;
        while(s!="")
        {
            string ss=div(add(s,"1"),2);
            s=div(s,2);
            ans=add(ans,mulit(ss,k));
            k++;
        }
        cout<

 

C Robot CleanerI

【题意】有一个机器人,有一个地图,这个机器人有一个执行的指令串;对于下一步要执行的指令有一个计算公式;然后计算最多可以捡起的垃圾数;

【分析】

因为地图上每个位置的数值是固定的,所以通过计算,只要不是捡垃圾的操作(使得这个位置数值为0)下一步的指令也是不变的;所以就直接模拟;

vis数组记录位置(a,b)走过多少次,f记录捡垃圾的次数,也就是整个地图变成新的地图的次数,也就是轮数;当走到(a,b)时还在这一轮说明进入了循环,就break掉;

【代码】

#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long ll;
const int maxn=2010;
char mp[maxn][maxn];
int vis[2010][2010];
char s[250];

ll cal(int x,int y){
    return 81*(mp[x][y]-'0')+27*(mp[x-1][y]-'0')+9*(mp[x+1][y]-'0')+3*(mp[x][y-1]-'0')+(mp[x][y+1]-'0');
}
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n,m;scanf("%d%d",&n,&m);
        int a,b;ll k;
        scanf("%d%d%lld",&a,&b,&k);
        scanf("%s",s+1);//注意这里下标从1开始
        for(int i=1;i<=n;++i)
            scanf("%s",mp[i]+1);
        memset(vis,0,sizeof(vis));
        int f=1,cnt=0;
        while(k--)
        {
            if(vis[a][b]==f)break;
            vis[a][b]++;
            int xx=cal(a,b)+1;
            char dig=s[xx];//cout<0 && mp[a-1][b]!='1')a--;
            else if(dig=='D' && a+1<=n && mp[a+1][b]!='1')a++;
            else if(dig=='L' && b-1>0 && mp[a][b-1]!='1')b--;
            else if(dig=='R' && b+1<=m && mp[a][b+1]!='1')b++;
            else if(dig=='P' && mp[a][b]=='2')
            {
                mp[a][b]='0';
                cnt++;
                f++;
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

E Potion

【题意】

首先n个数表示需求,再n个数表示库存;按等级递增读入;

等级高的可以降级给等级低的用,并且可以多次降级多次;

问能否成功满足所有需求

【分析】

从高等级往低等级遍历,多的就加到相邻的低等级上,看最后能否完成

【代码】

#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long ll;
const int maxn=110;
ll a[maxn],b[maxn];

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n;scanf("%d",&n);
        for(int i=0;i=0;--i)
        {
            if(b[i]>=a[i])
            {
                if(i!=0)b[i-1]+=b[i]-a[i];
                f=1;
            }
            else
            {
                f=0;break;
            }
        }
        if(f)puts("Yes");
        else puts("No");
    }
    return 0;
}

G Postman

【题意】邮局在原点,一个人送信每次最多拿k封,k封送完之后要返回邮局继续拿信,问送完所有的信走的最低路程

【分析】以原点分割为两端,均从绝对值最大的那段开始遍历,i+=k,路程乘2,最后两端的路程加起来,分别减去负值最小的那个和正值最大的那个,然后求min;如果全正或全负,再特殊处理一下(把原始序列的绝对值存进aa数组)

【代码】

#include
#include
#include
#include
#include
#include
#include
using namespace std;

const int maxn=1e5+10;
typedef long long ll;
vectora,b;
ll aa[maxn];

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n,k;scanf("%d%d",&n,&k);
        a.clear();b.clear();
        memset(aa,0,sizeof(aa));
        for(int i=0;i0)b.push_back(x);
            if(x<0)x=-x;aa[i]=x;
        }
        sort(a.begin(),a.end());
        sort(b.begin(),b.end());
        int len1=a.size(),len2=b.size();
        ll ans1=0;
        int num;
        if(len1==0 || len2==0)
        {
            sort(aa,aa+n);
            for(int i=n-1;i>=0;i-=k)
                ans1+=aa[i]+aa[i];
            ans1-=aa[n-1];
            printf("%lld\n",ans1);
            continue;
        }
        for(int i=0;i=0;i-=k)
            ans1+=b[i]+b[i];
        printf("%lld\n",min(ans1+a[0],ans1-b[len2-1]));
    }
    return 0;
}

J  Extended Twin Composite Number

【题意】输入一个n,输出x,y 满足 x + n = y 并且x,y都是合数

【分析】

因为输入n,大方向来说n是有奇偶之分的;

首先写出前几个合数:4 6 8 9 10 12 14 15 16 18 20...

如果n是偶数,那么就有 x+2n=y, 使得x和y都是偶数则x是偶数即可,所以取第一个合数4,则 输出4  n+4

如果n是奇数,那么就有x+2n+1=y,让y变成偶数,取第一个奇数合数9,输出 9 n+9

【代码】

#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long ll;

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        ll n;scanf("%d",&n);
        if(n%2==0)
        {
            printf("4 %lld\n",n+4);
        }
        else printf("9 %lld\n",n+9);
    }
    return 0;
}

 

你可能感兴趣的:(string字符串,算法&理论,思维,模拟,板子)