CF 1538 G. Gift Set (贪心+思维)

简介: 【6月更文挑战第14天】

链接

题意:

Polycarp有x个红糖和y个蓝糖,现在他想用这些糖果做一些礼品盒(gift set),但规定每个礼品盒里必须有a个红糖、b个蓝糖或b个红糖、a个蓝糖。现在求他最多能做成多少个礼品盒。

分析:

首先我们会发现这个题有很多种方法:二分($O(log(n))$),模拟($O(1)$),模拟退火等,

二分:

既然他是最多能做多少,那么我们可以发现,答案满足单调性,那么我们直接二分答案就好了。
首先我们找到那个用的糖果更少,假设a的更少。那么我们枚举的答案,一定满足:$x-aans>=0;y-aans>=0;$这是肯定的,因为如果用的少的都不满足跟不用提多的了,然后我们看如果$a=b$那么他一定是满足条件的,否则就是$a=ans$这样就是满足条件的,否则不满足。为什么那?其实就是用剩下的空变化一下成b,由a变成b需要加上$b-a$所以我们看有多少可以转化成b,如果比ans大或者相等那么这个ans是可以的,否则就不可以。

void solve(){
   
    scanf("%lld%lld%lld%lld", &n, &m, &a, &b);
    if(a>b) swap(a,b);
    ll l=0,r=1e9+7;
    while(l<r){
   
        ll mid=(l+r)/2;
        ll x=n,y=m;
        x-=a*mid;
        y-=a*mid;
        bool flag=(x>=0&&y>=0);
        if(b>a){
   ///防止出现a=b导致除以负数
            if(x/(b-a)+y/(b-a)<mid) flag=0;
        }
        if(flag) l=mid+1;
        else r=mid;
    }
    cout<<l-1<<endl;
}

模拟($O(1)$)

我们让n<m,a<b
我们分析出来他其实就是那么 一些(a+b,a+b)这样的二元组,和一些(a,b)这样的二元组。
我们发现我们选一个二元组(a,b)会让(n,m)之间的差缩减(b-a).所以我们可以先选$\frac{m-n}{b-a}$个(a,b)剩下的可以全选(a+b,a+b);

如果我们最后选完(a+b,a+b),还剩的够再买一个(a,b)或者(b,a)这样的二元组,那么我们就需要在做一次贡献。

需要特判一下,a=b因为不能除以0.答案是($\frac{n}{a}$)

void solve()
{
   
    scanf("%lld%lld%lld%lld", &n, &m, &a, &b);    
    ///O(1)
    if(n>m) swap(n,m);
    if(a>b) swap(a,b);
    if(n<a||m<b) {
   
        puts("0");
        return ;
    }
    ll ca=m-n,cb=b-a;
    if(cb==0){
   
        printf("%lld\n",n/a);
        return;
    }
    ll num=min(ca/cb,min(n/a,m/b));
    n-=num*a;m-=num*b;
    ll ans=num+min(n,m)/(a+b)*2;
    if(n>=a&&m>=b) n-=a,m-=b,num++;
    printf("%lld\n",max(ans,num+min(n,m)/(a+b)*2));
}

链接

题意:

给出二维平面上的 $n$ 个点,任意选择出三个点可以构成一个三角形,现在问满足下面条件的三角形的个数:

  • 三角形面积为整数
  • 三角形包含的(不包括边界)整数点为奇数
  • 其中所有坐标点的 $x$ 和 $y$ 都是偶数

    分析:

    首先看下需要用到的定理之类的东西:
  1. 已知三角形三个点,求三角形面积
    $S=\frac{x_1(y_2-y_3)+x_2(y_3-y_1)+x_3(y_1-y_2)}{2}$
  2. 皮克定理
    用于求多边形面积。$S=a+\frac{b}{2}-1$其中a是多边形内部的整点数,b是多边形边界点数。S是多边形面积。边界上的点数为$gcd(x_1-x_2,y_1-y_2)+1$
// Problem: F1. Gregor and the Odd Cows (Easy)
// Contest: Codeforces - Codeforces Round #736 (Div. 2)
// URL: https://codeforces.com/contest/1549/problem/F1
// Memory Limit: 256 MB
// Time Limit: 6000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define x first
#define y second
#define sf scanf
#define pf printf
#define PI acos(-1)
#define inf 0x3f3f3f3f
#define lowbit(x) ((-x)&x)
#define mem(a,x) memset(a,x,sizeof(a))
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
#define debug(x) cout << #x << ": " << x << endl;

const int MOD = 998244353;
const int mod = 1e9 + 7;
const int maxn = 2e5 + 10;    
const int dx[] = {
   0, 1, -1, 0, 0};
const int dy[] = {
   0, 0, 0, 1, -1};
const int dz[] = {
   1, -1, 0, 0, 0, 0 };
int day[] = {
   0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

ll dp[2][2];

ll C(ll n,ll m){
   
    if(m==1) return n;
    else if(m==2)return n*(n-1)/2;
    else if(m==3) return (n-1)*(n-2)*n/6;
}

void solve()
{
   
    ll n;    
    scanf("%lld\n",&n);
    for(int i=1;i<=n;i++){
   
        int x, y;
        scanf("%d%d",&x,&y);
        dp[x%4/2][y%4/2]++;
    }
    ll ans=0;
    for(ll i=0;i<4;i++){
   
        for(ll j=i;j<4;j++){
   
            for(ll k=j;k<4;k++){
   
                ll x1=i/2,y1=i%2;
                ll x2=j/2,y2=j%2;
                ll x3=k/2,y3=k%2;
                ll sum=0;
                sum+=(x1==x2&&y1==y2);
                sum+=(x3==x2&&y3==y2);
                sum+=(x1==x3&&y1==y3);
                if(sum==0||sum==2) continue;
                if(i==j&&i==k) ans+=C(dp[x1][y1],3);
                else if(i==j) ans+=C(dp[x1][y1],2)*dp[x3][y3];
                else if(k==j) ans+=C(dp[x2][y2],2)*dp[x1][y1];
                else if(i==k) ans+=C(dp[x1][y1],2)*dp[x2][y2];
                else ans+=dp[x1][y1]*dp[x2][y2]*dp[x3][y3];
            }
        }
    }
    cout<<ans<<endl;
}

int main()
{
   
    ll t = 1;
    //scanf("%lld",&t);
    while(t--)
    {
   
        solve();
    }
    return 0;
}
目录
相关文章
|
1月前
|
存储 JavaScript 前端开发
Set、Map、WeakSet 和 WeakMap 的区别
在 JavaScript 中,Set 和 Map 用于存储唯一值和键值对,支持多种操作方法,如添加、删除和检查元素。WeakSet 和 WeakMap 则存储弱引用的对象,有助于防止内存泄漏,适合特定场景使用。
|
2月前
|
存储 Java API
【数据结构】map&set详解
本文详细介绍了Java集合框架中的Set系列和Map系列集合。Set系列包括HashSet(哈希表实现,无序且元素唯一)、LinkedHashSet(保持插入顺序的HashSet)、TreeSet(红黑树实现,自动排序)。Map系列为双列集合,键值一一对应,键不可重复,值可重复。文章还介绍了HashMap、LinkedHashMap、TreeMap的具体实现与应用场景,并提供了面试题示例,如随机链表复制、宝石与石头、前K个高频单词等问题的解决方案。
37 6
【数据结构】map&set详解
|
1月前
|
存储 缓存 Java
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
35 1
|
2月前
|
算法
你对Collection中Set、List、Map理解?
你对Collection中Set、List、Map理解?
36 5
|
2月前
|
存储 JavaScript 前端开发
js的map和set |21
js的map和set |21
|
2月前
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
|
3月前
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
3月前
|
Java
【Java集合类面试二十二】、Map和Set有什么区别?
该CSDN博客文章讨论了Map和Set的区别,但提供的内容摘要并未直接解释这两种集合类型的差异。通常,Map是一种键值对集合,提供通过键快速检索值的能力,而Set是一个不允许重复元素的集合。
|
3月前
|
存储 JavaScript 前端开发
ES6新特性(四): Set 和 Map
ES6新特性(四): Set 和 Map