暑期团队赛

 

到了与队友合作比拼的时刻了,这场可能将会是一场关乎icpc现场赛名额的比赛呢,虽然如今已经拿到了名额,但现在回忆起来,这场比赛确实还是意义非凡呢


作为这场参赛队伍中唯一一只拿到现场赛名额的队伍,然而,其实感觉这场很多题目都是可做的,还是缺乏配合吧。现在想想,最后的icpc现场赛的名额还是靠乌鲁木齐网赛rank1超越校金牌队的逆天表现而拼下来的,也算是一次难以忘怀的回忆了吧

 

 

1240 Problem D Godv与女朋友赛马

 

思路:典型的签到题,两数组排个序比较一下就ok了,从数模场强行赶往团队赛赛场,惊奇的发现队友已经把这题ac了,确实喜出望外啊

 

/*
Author Owen_Q
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1e5+10;

int a[maxn],b[maxn];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int score = 0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        sort(a,a+n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&b[i]);
        }
        sort(b,b+n);
        for(int apos=0,bpos=0;apos<n&&bpos<n;apos++,bpos++)
        {
            while(a[apos]>=b[bpos])
            {
                bpos++;
                if(bpos>=n)
                {
                    break;
                }
            }
            if(bpos<n)
            {
                score++;
            }
        }
        if(score==0)
        {
            printf("Godv too strong\n");
        }
        else
        {
            printf("%d\n",score);
        }
    }
    return 0;
}

 

1241 Problem E 余神的rp机

 

 

思路:经典dp

区间处理问题,那就先预处理区间最大值

之后按问题dp,对于m个核芯,n个时间段,dp由少一个核芯转移而来

 

/*
Author Owen_Q
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 510;

int s[maxn];

int inter[maxn][maxn];
int dp[maxn][maxn];

int main()
{
    int t;
    while(scanf("%d",&t)!=EOF)
    {
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&s[i]);
            }
            memset(inter,0,sizeof(inter));
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
            {
                inter[i][i] = s[i];
                for(int j=i+1;j<=n;j++)
                {
                    inter[i][j] = min(inter[i][j-1],s[j]);
                }
            }
            for(int i=1;i<=m;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    dp[i][j] = dp[i-1][j];
                    for(int k=0;k<=j-1;k++)
                    {
                        dp[i][j] = max(dp[i][j],dp[i-1][k]+inter[k+1][j]*(j-k));
                    }
                }
                for(int j=2;j<=n;j++)
                {
                    dp[i][j] = max(dp[i][j],dp[i][j-1]);
                }
            }
            printf("%d\n",dp[m][n]);
            /*for(int i=1;i<=m;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    printf("%d ",dp[i][j]);
                }
                printf("\n");
            }*/
        }
    }
    return 0;
}

 

 

再加个小tip,通过本题第一次写了对拍的bat,瞬间感觉自己又学到了不少东西,来看看吧

 

#Author Owen_Q


@echo off
:again
	rand.exe %random% > in.txt
	standard.exe < in.txt > output.txt
	余神的rp机.exe < in.txt > my.txt
	fc /A output.txt my.txt 
if not errorlevel 1 goto again
pause
goto again


然后加个随机数生成器

 

 

/*
Author Owen_Q
*/

#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<sstream>
#include<ctime>

using namespace std;

#define random(a,b) ((a)+rand()%((b)-(a)+1))

stringstream ss;

int main(int argc, char *argv[])
{
	int seed=time(NULL);
    if(argc)//如果有参数
    {
        ss.clear();
        ss<<argv[1];
        ss>>seed;//把参数转换成整数赋值给seed
    }
    srand(seed);
    //以上为随机数初始化,请勿修改
    //random(a,b)生成[a,b]的随机整数

    int t = random(1,5);
    cout << t << endl;
    while(t--)
    {
    	int n,m;
    	n = random(1,10);
    	m = random(1,10);
    	while(m>n)
    	{
    		m = random(1,10);
    	}
    	cout << n << " " << m << endl;
    	for(int i=1;i<n;i++)
    	{
    		int s = random(0,500);
    		cout << s << " " ;
    	}
    	cout << random(0,500) << endl;
    }
    return 0;
}


完美

 

 

1243 Problem G CKJ老师爱数学

思路:这题当几何题做了好久,基本耽搁了整场,然而到头来才发现原来是个数论题,其实原来也想过优化枚举,但一旦思路跑偏了,就再也回不来了

简单的思路写代码前面了,直接看吧

 

/*
Author Owen_Q
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

/*
x^2 + y^2 = z^2
x^2 = z^2 - y^2
x^2 = (z-y) * (z+y)
令 d = gcd(z-y,z+y)
故 (z-y)/d 与 (z+y)/d 互质
则 z-y = d * u^2
z+y = d * v^2
因此
2z = d * (u^2 + v^2)
2y = d * (u^2 - v^2)
x = d * u * v
u v 互质
*/

using namespace std;

const long long maxn = 1e5+10;

vector <long long> factor;

void get_factor(long long x)
{
    factor.clear();
    long long i;
    for(i=1;i*i<x;i++)
    {
        if(x%i==0)
        {
            factor.push_back(i);
            factor.push_back(x/i);
        }
    }
    if(i*i==x)
    {
        factor.push_back(i);
    }
    return ;
}

long long gcd(long long a,long long b)
{
	return b == 0 ? a : gcd(b, a % b);
}

long long isSquare(long long x)
{
    long long i = sqrt((double)(x+1e-9));
    if(i*i == x)
    {
        return i;
    }
    else
    {
        return -1;
    }
}

int main()
{
    long long z;
    int t;
    scanf("%d",&t);
    //freopen("in.txt","r",stdin);
    //freopen("my.txt","w",stdout);
    /*for(long long i=1;i<=2000;i++)
    {
        cout << i << endl;
    }*/
    while(t--)
    {
        scanf("%lld",&z);
        long long sum = 0;
        get_factor(2*z);
        long long len = factor.size();
        //cout << "*" << endl;
        for(long long d=0;d<len;d++)
        {
            //cout << factor[d] << endl;
            for(long long u=1;u*u<z/factor[d];u++)
            {
                //cout << "**" << endl;
                long long v = isSquare(2*z/factor[d] - u*u);
                if(v > 0&&gcd(u,v)==1)
                {
                    sum++;
                    //cout << (v*v-u*u) * factor[d] / 2 << "**" << u*v*factor[d] << endl;
                    //cout << u <<"*"<< v <<"*"<< factor[d]<<endl;
                }
            }
        }
        sum *= 4;
        sum += 4;
        printf("%lld\n",sum);
    }
    return 0;
}


1239 Problem C Glory And Xor/Or

 

思路:这题其实是典型团队合作的成果,队友想到枚举所有数判断,然而n为1e5,完全可以加个小数量级的复杂度,果断想到按位判断,从高位开始,依次处理。

而异或问题其实就相当于分割问题,变相插板法的排列组合

最后就是要注意一下移位操作

 

/*
Author Owen_Q
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1e5+10;

int a[maxn];
int last[maxn];
int now[maxn];

int main()
{
    int t;
    while(scanf("%d",&t)!=EOF)
    {
        while(t--)
        {
            int n,k;
            int re = 0;
            scanf("%d%d",&n,&k);
            for(int i=0;i<n;i++)
            {
                scanf("%d",&a[i]);
            }
            if(k==0)
            {
                printf("0\n");
                continue;
            }
            memset(now,0,sizeof(now));
            memset(last,0,sizeof(last));
            for(int i=30;i>=0;i--)
            {
                ///cout << endl << now[0] << " ";
                now[0] = (a[0]&(1<<i))>>i;
                for(int j=1;j<n;j++)
                {
                    now[j] = now[j-1] ^ ((a[j]&(1<<i))>>i);
                    //cout << now[j] << "*" << (a[j]&(1<<i)) << "*" << i <<  " ";
                }
                if(now[n-1]==1)
                {
                    re |= (1<<i);
                    //cout << "*";
                }
                else
                {
                    int num = 0;
                    for(int j=0;j<n;j++)
                    {
                        now[j] |= last[j];
                        if(now[j]==0)
                        {
                            num++;
                        }
                    }
                    if(num>=k)
                    {
                        for(int j=0;j<n;j++)
                        {
                            last[j] = now[j];
                        }
                        //cout << "$";
                    }
                    else
                    {
                        re |= (1<<i);
                        //cout << "*";
                    }
                }
                /*for(int i=0;i<n;i++)
                {
                    //cout << last[i] << " ";
                }*/
            }
            printf("%d\n",re);
        }
    }
    return 0;
}


icpc之旅奋斗启程

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值