EOJ Mouthly 2018.4

A. ultmaster 的小迷妹们

Time limit per test: 2.0 seconds

Memory limit: 256 megabytes

ultmaster 男神和他的小迷妹们准备躺在图书馆前大草坪享受惬意的午后。

有强迫症的 ultmaster 想要使得自己和小迷妹们正好躺成一块完整的正方形,ultmaster 想知道能否挑出一些小迷妹(至少一个)实现他的愿望。

已知 ultmaster 的形状 n×n 的正方形,小迷妹的形状为 x×y 的长方形(可以横着或者竖着躺)。若能够则输出Yes 否则输出 No

P.S. ultmaster 是正方形因为他比较肥。

Input

第一行三个整数 n,x,y (1n,x,y109) 分别表示描述中的 n,x,y

Output

输出一行字符串,Yes 或 No 表示 ultmaster 能否实现他的愿望。

Examples

input
1 1 2
output
Yes
input
1 2 2
output
No

Note

样例一:可以构成 3×3 的正方形。


题解:

对于这个题解怎么理解呢:给出题解

考虑小正方形所在列,一定不能被gcd整除,小正方形所不在列,一定能被gcd整除,所以一定不能拼成大正方形。
如果能被gcd整除,则由扩展欧几里得一定存在axby=n,因此可以构成n×n在中间,四个ax×by在周围的正方形

代码就很简单了

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

int main()
{
    int n,x,y;
    while(~scanf("%d%d%d",&n,&x,&y))
    {
        int gcd = __gcd(x,y);
        if(n % gcd == 0) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
B. 代码查重

Time limit per test: 2.0 seconds

Memory limit: 256 megabytes

一场 EOJ 月赛中在小迷妹们的合作之下她们 AC 了所有题目。

拥有 EOJ 管理员权限的 ultmaster 男神理所当然地抄袭了小迷妹们的代码,并修改了部分代码。ultmaster 男神想知道他的代码是否会被查重,若会被查重则输出 Yes 否则输出 No。由于 EOJ 查重系统比较弱智,所以两份代码会被查重的充要条件是,每行代码对应的哈希值都完全同义。

注:同义关系满足自反性,对称性,但不满足传递性

  • 自反性:对于任意 x 同义于 x
  • 对称性:对于任意 x,y,如果 x 同义于 y,则 y 同义于 x
  • 传递性:对于任意 x,y,z,如果 x 同义于 yy 同义于 z,则 x 同义于 z

Input

第一行三个整数 n,m,k (1n,m,k105) 分别表示小迷妹们的代码行数,ultmaster 代码长度,EOJ 查重系统默认的同义关系个数。

第二行 n 个整数 a1,a2,,an (1ai109),表示小迷妹们代码每行的哈希值。

第三行 m 个整数 b1,b2,,bm (1bi109),表示 ultmaster 代码每行的哈希值。

接下去 k 行,每行两个整数 x,y (1x,y109),表示哈希值为 x 和 哈希值为 y 同义。同一对 x,y 可能重复出现。

Output

输出一行字符串,Yes 或 No 表示 ultmaster 男神的代码是否会被查重。

Examples

input
1 1 2
1
3
1 2
2 3
output
No
input
2 2 1
1 1
2 2
1 2
output
Yes
题解:

直接用set存储加判断就好

注意两个坑点:1.长度可能不同(因为题意被坑的深感歉意)。2.自反性意味着两个完全相同的同义。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
map<int,int> ID;
vector<int> store;
int ult[maxn],mim[maxn];
int getID(int str) {
    if(ID.find(str) == ID.end())
    {
        store.push_back(str);
        ID[str] = store.size() - 1;
    }
    return ID[str];
}
void init() {
    ID.clear();
    store.clear();
}
set<int> way[maxn];
int main()
{
    int n,m,k;
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        for(int i=0;i<maxn;i++) way[i].clear();
        init();
        for(int i=0;i<n;i++) {
            scanf("%d",&ult[i]);
            getID(ult[i]);
        }
        for(int i=0;i<m;i++) {
            scanf("%d",&mim[i]);
            getID(mim[i]);
        }

        for(int i=0,u,v;i<k;i++) {
            scanf("%d%d",&u,&v);
            int x = getID(u),y = getID(v);
            way[x].insert(y);
            way[y].insert(x);
        }
        bool flag = true;
        for(int i=0;i<n&&i<m;i++) {
            int x = getID(ult[i]),y = getID(mim[i]);
            if( way[x].count(y) == 0 && x != y  && way[y].count(x) == 0) {
                flag = false;
                break;
            }
        }
        if(n != m) flag = false;
        if(flag) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
E. 小迷妹在哪儿

Time limit per test: 2.0 seconds

Memory limit: 256 megabytes

ultmaster 男神和小迷妹们玩起了捉迷藏的游戏。

小迷妹们都希望自己被 ultmaster 男神发现,因此她们都把自己位置告诉了 ultmaster 男神,因此 ultmaster 男神知道了自己去找每个小迷妹所要花的时间。

已知发现第 i 小迷妹得到的分数为 aitrtr 为游戏剩余时间)。ultmaster 想知道他最多能拿多少分。

Input

第一行两个整数 n,T (1n105,1T300) 分别表示小迷妹数量,游戏总时间。

接下去 n 行,每行两个整数 ai,ti (1ai100,1ti300) 分别表示发现小迷妹的分数以及 ultmaster 男神发现小迷妹所需时间。

Output

一个整数,表示 ultmaster 在游戏中最多拿多少分。

Examples

input
2 10
2 5
1 6
output
10
input
3 5
5 4
1 1
10 6
output
5

Note

样例一:找到小迷妹一,找到后得分 2×(105)=10 分。
样例二:找到小迷妹一,找到后得分 5×(54)=5 分,之后再找到小迷妹二得分也是 0,所以最高得分 5 分。


题解:表示这题山东省赛有出过类似的...貌似还更难:有兴趣可以看看 地址

尽可能先找到性价比高的小迷妹,所以按性价比排个序,然后就是个裸的背包。
证明:交换任意两个小迷妹的顺序可以列不等式证明性价比高的先找更优。

ps:原来想研究cf赛制应该先做难题还是简单题。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
struct Mim {
    int a,t;
}mim[maxn];
bool cmp(const Mim &aa,const Mim &bb) {
    return aa.a * bb.t > aa.t * bb.a;
}
int dp[maxn];
int main()
{
    int n,T;
    while(~scanf("%d%d",&n,&T))
    {
        for(int i=1;i<=n;i++)
            scanf("%d%d",&mim[i].a,&mim[i].t);
        sort(mim+1,mim+1+n,cmp);

        dp[0] = 0;
        int ans = 0;
        for(int i=1;i<=n;i++) {
            for(int j=0;j<=T;j++)
                if(j >= mim[i].t) {
                    dp[j - mim[i].t] = max(dp[j-mim[i].t],dp[j] + mim[i].a * (j-mim[i].t));
                    ans = max(ans,dp[j-mim[i].t]);
                }
        }
        printf("%d\n",ans);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值