第一题:Laptops
题意:Dima 和 Alex 在争论笔记本的价格和质量的关系。Dima认为笔记本的价格越高,笔记本的质量也越好。Alex认为一定有两台笔记本,第一台的价格严格低于第二台的,但是第一台的质量严格好于第二台。现在给你一组数据(1<=ai,bi<=n,ai和bi分别唯一) ,分别代表第i台笔记本的价格和质量,问这组数据能否证明Alex的说法。
题解:读入ai和bi后,依ai从小到大排序,如果bi不是依次递增,即存在Alex提及的情况。
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 0x6fffffff
struct node
{
int a,b;
} num[100005];
bool cmp(const struct node &a,const struct node &b)
{
return a.a<b.a;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0; i<n; ++i)
{
scanf("%d%d",&num[i].a,&num[i].b);
}
if(n==1)
{
printf("Poor Alex\n");
return 0;
}
sort(num,num+n,cmp);
bool flag=true;
for(int i=0; i<n; ++i)
{
if(num[i].b!=i+1)
{
printf("Happy Alex\n");
flag=false;
break;
}
}
if(flag)
printf("Poor Alex\n");
return 0;
}
第二题:Fedya and Maths
题意:求(1n + 2n + 3n + 4n) mod 5的值,n可能非常大
题解:根据模运算规则,(a+b)%p=(a%p+b%p)%p (a*b)%p=(a%p*b%p)%p ,会发现该算式的值是4 0 0 0的循环,因此问题就转化为判断n是否是4的倍数,而判断是否是4的倍数可以通过计算最后两位是否能被4整除得出(或者直接使用java中的大数类)
代码:
import java.io.BufferedInputStream;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[]args){
BigInteger n;
BigInteger f=new BigInteger("4");
Scanner cin = new Scanner (new BufferedInputStream(System.in));
n=cin.nextBigInteger();
if(n.mod(f).equals(new BigInteger("0"))){
System.out.println("4");
}
else{
System.out.println("0");
}
}
}
第三题:Boredom
题意:Alex 创造了一个游戏。给一串数字(1 ≤ ai ≤ 105),玩家可以走很多步,每步删除一个元素ak(只删除一个),同时删除数字串中所有等于ak-1和ak+1的元素,玩家在这步中得到ak分。问在给定的数字串中最大可以得多少分。
题解:动态规划。dp[i][0]代表不选取数字i,dp[i][1]代表选择数字i。
转移方程: dp[i][0]=max(dp[i-1][0],dp[i-1][1])//不选数字i,所以数字i-1可选可不选
dp[i][1]=dp[i-1][0]+num[i]*i//选数字i的状态只能是从不选数字i-1传递过来的
由于数据范围比较大,最好采用__int64定义变量
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 0x6fffffff
#define N 100005
#define max(a,b) (a)>(b)?(a):(b)
__int64 num[N];
__int64 dp[N][2];
int main()
{
int n,a,maxx=0;
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%d",&a);
maxx=max(maxx,a);
++num[a];
}
for(int i=1;i<=maxx;++i)
{
dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
dp[i][1]=dp[i-1][0]+num[i]*i;
}
printf("%I64d\n",max(dp[maxx][0],dp[maxx][1]));
return 0;
}