Round G 2019 - Kick Start 2019

https://codingcompetitions.withgoogle.com/kickstart/round/0000000000050e02/000000000018fd0d

Book Reading (10pts, 15pts)

1 ≤ T ≤ 100.
1 ≤ P1 < P2 < ... < PM ≤ N.
1 ≤ Ri ≤ N, for all i.

Test set 1 (Visible)

1 ≤ M ≤ N ≤ 1000.
1 ≤ Q ≤ 1000.

Test set 2 (Hidden)

1 ≤ M ≤ N ≤ 105.
1 ≤ Q ≤ 105.

题意:一本书有 1……n页,撕去 p 页,有 q 个读者, 问读者一共能阅读的页数

如果直接枚举暴力的话, 10ps 到手

#include<bits/stdc++.h>

using namespace std;
#define _for(i,a,b) for(int i = (a); i < (b); i++)
#define _rep(i,a,b) for(int i = (a); i <= (b); i++)
const int N = 1e5+100;
int a[N],b[N],vis[N];

int main(){
    ios::sync_with_stdio(0); cin.tie(0);
    int t,n,m,q,kase = 1; cin >>t ;
    while(t--) {
        cin >> n >> m >> q; int x,cnt = 0;
        memset(vis, 0, sizeof(vis));
        _for(i,0,m) cin >> x, vis[x] = 3;
        _for(i,0,q) {
            cin >> x;
            for(int j = x; j <= n; j += x)
                if(vis[j] != 3) cnt++;
        }

        cout << "Case #"<< kase++ << ": ";
        cout << cnt << endl;
    }
    return 0;
}

但是很明显, 会 TLE, 所以需要优化下

#include<bits/stdc++.h>

using namespace std;
#define _for(i,a,b) for(int i = (a); i < (b); i++)
#define _rep(i,a,b) for(int i = (a); i <= (b); i++)
#define ll long long
const int N = 1e5+100;

int main(){
    ios::sync_with_stdio(0); cin.tie(0);
    int t,n,m,q,kase = 1; cin >>t ;
    while(t--) {
        vector<int> a(N, 0);
        vector<bool> vis(N, false);
        cin >> n >> m >> q; int x;
        ll cnt = 0;
        _for(i,0,m) cin >> x, vis[x] = true;
        _for(i,0,q) {
            cin >> x;
            if(a[x]){
                cnt += a[x];
                continue;
            }

            for(int j = x; j <= n; j += x)
                if(!vis[j]) a[x]++;
            cnt += a[x];
        }

        cout << "Case #"<< kase++ << ": ";
        cout << cnt << endl;
    }
    return 0;
}

https://codingcompetitions.withgoogle.com/kickstart/round/0000000000050e02/000000000018fe36
The Equation (12pts, 20pts)

直接暴力 12pts可到手

#include<bits/stdc++.h>

using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define scld(x) scanf("%lld", &x)
#define prcas printf("Case #%d: ", cas)
#define pncas printf("Case #%d:\n", cas)
#define lowbit(x) ((x) & (-(x)))
#define fi first
#define se second
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef vector<int> vi;

const int maxn = 25;
int dp[1048550];
LL a[maxn], b[maxn];
int n, T, h;

int main()
{
    scanf("%d", &T);
    for(int cas = 1; cas <= T; ++ cas)
    {
        scanf("%d %d", &n, &h);
        for(int i = 0; i < n; ++ i) scld(a[i]);
        //for(int i = 0; i < n; ++ i) scld(b[i]);
        prcas; int flag = 0;
        for(int i = 128; i >= 0; i--){
            int sum = 0;
            for(int j = 0; j < n; j++)
                sum += a[j]^i;
            if(sum <= h) {
                flag = 1; printf("%d\n", i);break;
            }
        }
        if(!flag) printf("-1\n");
    }
    return 0;
}

通过对 k 的二进制位数进行枚举, cnt[i][0]   cnt[i][1]分别记录 数组a的 第i+1位的 0 与 1的个数

再通过 ret[i][0]  ret[i][1] 分别表示对前 i 位的a数组的 0 与 1 表示的和

然后 通过 suf[i] 记录前 i 项 min(ret[i][0], ret[i][1])的和, (???)
然后枚举 位数 i 51~0 如果符合 ret[i][1]+suf[i-1]  k |= 1<<i , 即 k 的这个二进制位为 1, 否则为 0  m-= ( 为1 ? ret[i][1] : ret[i][0])
若枚举结束  m < 0, 则不存在 k

#include<bits/stdc++.h>

using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;

#ifdef __LOCAL_DEBUG__
# define _debug(fmt, ...) fprintf(stderr, "[%s] " fmt "\n",     __func__, ##__VA_ARGS__)
#else
# define _debug(...) ((void) 0)
#endif

#define IN freopen("B.in", "r", stdin)
#define OUT freopen("B.out", "w", stdout)
#define scd(x) scanf("%d", &x)
#define scld(x) scanf("%lld", &x)
#define scs(x) scanf("%s", x)
#define mp make_pair
#define pb push_back
#define sqr(x) (x) * (x)
#define prcas printf("Case #%d: ", cas)
#define pncas printf("Case #%d:\n", cas)
#define lowbit(x) ((x) & (-(x)))
#define fi first
#define se second
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef vector<int> vi;

const int maxk = 51;
int cnt[65][2];
int n, T;
LL m, ans, ret[65][2], suf[65];

int main()
{
    scd(T);
    for(int cas = 1; cas <= T; ++ cas)
    {
        for(int i = 0; i <= maxk; ++ i) cnt[i][0] = cnt[i][1] = 0;
        scanf("%d%lld", &n, &m);
        while(n --)
        {
            LL x; scanf("%lld", &x); ans = 0;
            for(int i = 0; i <= maxk; ++ i, x >>= 1) cnt[i][x & 1] ++;
        }
        for(int i = 0; i <= maxk; ++ i)
            ret[i][0] = 1ll * cnt[i][1] * (1ll << i), ret[i][1] = 1ll * cnt[i][0] * (1ll << i);
        suf[0] = min(ret[0][0], ret[0][1]);
        for(int i = 1; i <= maxk; ++ i)
            suf[i] = suf[i - 1] + min(ret[i][0], ret[i][1]);
        for(int i = maxk; i >= 0 && m >= 0; -- i)
        {
            LL t = 0; if(i > 0) t = suf[i - 1];
            if(ret[i][1] + t <= m)
            {
                ans |= 1ll << i;
                m -= ret[i][1];
            }else m -= ret[i][0];
        }
        if(m < 0) ans = -1;
        prcas; printf("%lld\n", ans);
    }
    return 0;
}
/*
Input
4
3 27
8 2 4
4 45
30 0 4 11
1 0
100
6 2
5 5 1 5 1 0

Case #1: 12
Case #2: 14
Case #3: 100
Case #4: -1
*/

https://codingcompetitions.withgoogle.com/kickstart/round/0000000000050e02/000000000018fd5e
Shifts (20pts, 23pts)

题意:有n个班次, h 快乐值要求, 问有多少种情况 a 与 b 都快乐(快乐值大于等于h)

如果直接暴力的话, 0~ 3^n-1, 暴力枚举 每个班次的三种情况(单选a, 单选b, 同时选ab),n<=12,5e5的样子,能过 Test set 1, 但Test set 2 3e8(n<=20)就会TLE

TLE

  #include<bits/stdc++.h>
  using namespace std;
  #define rep(x,y) for(long long i =x;i<=y;i++)
  #define pb push_back
  #define mp make_pair
  #define ALL(x) (x).begin(),(x).end()
  #define FastIO  ios_base::sync_with_stdio(false); cin.tie(NULL);
  typedef long long ll;
  typedef pair< ll, ll> pll;
  typedef vector< ll > vll;
  typedef map < ll, ll > mll;

int main()
{
  ll i,j,t,test,ans,n,num,s1,s2,a[30],b[30],h,ways;
  test=1;
  cin >> t;
  while(t--)
  {
    cout << "Case #" << test << ": " ;
    ans=0;
    test++;
    cin >> n >> h;
    rep(1,n)
      cin >> a[i];
    rep(1,n)
      cin >> b[i];
    ways= pow(3,n)-1;
    rep(0,ways)
    {
      num=i;
      j=1;
      s1=0;
      s2=0;
      while(j<=n)
      {
        if(num%3==0)
        {
          s1+=a[j];
        }
        else if(num%3==1)
          s2+=b[j];
        else
        {
          s1+=a[j];
          s2+=b[j];
        }
        num/=3;
        j++;
      }
    //  cout << s1 << " " << s2 << endl;
      if(s1>=h && s2>=h)  ans++;
    }
    cout << ans << endl;
  }
  return 0;
}

dp[mask]  mask 0~2^n-1, 以0 1 分 n个a是否被取
then  mask 0~2^n-1  i 0~n  dp[mask^(1<<i)] += dp[mask]

then  x 0~2^n-1  dp[x]  2^n-x-1(二进制01 代表n个b是否被取)    神奇的穷举操作
最后会发现 所有的可能 3^n 都被枚举了

比如说 n = 2, 
            a           b

dp[0] = 00 01 10 11    11

dp[1] = 01 11      10

dp[2] = 10 11      01

dp[3] = 11        00

#include<bits/stdc++.h>

using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define scld(x) scanf("%lld", &x)
#define prcas printf("Case #%d: ", cas)
#define pncas printf("Case #%d:\n", cas)
#define lowbit(x) ((x) & (-(x)))
#define fi first
#define se second
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef vector<int> vi;

const int maxn = 25;
int dp[1048550];
LL a[maxn], b[maxn];
int n, T, h;

int main()
{
    scanf("%d", &T);
    for(int cas = 1; cas <= T; ++ cas)
    {
        scanf("%d %d", &n, &h);
        for(int i = 0; i < n; ++ i) scld(a[i]);
        for(int i = 0; i < n; ++ i) scld(b[i]);
        for(int mask = 0; mask < (1 << n); ++ mask)
        {
            LL sum = 0;
            for(int i = 0; i < n; ++ i)
                if((mask >> i) & 1) sum += a[i];
            if(sum >= h) dp[mask] = 1; else dp[mask] = 0;
        }
//for(int mask = 0; mask < (1 << n); ++ mask) printf("dp[%d]= %d  ", mask, dp[mask]);printf("\n");
        for(int i = 0; i < n; ++ i)
            for(int mask = 0; mask < (1 << n); ++ mask)
                if((mask >> i) & 1) dp[mask ^ (1 << i)] += dp[mask];
        LL ans = 0;
//for(int mask = 0; mask < (1 << n); ++ mask) printf("dp[%d]= %d  ", mask, dp[mask]);printf(" \t...\n");
        for(int mask = 0; mask < (1 << n); ++ mask)
        {
            LL sum = 0, task = 0;
            for(int i = 0; i < n; ++ i)
                if((mask >> i) & 1) sum += b[i];
                else task |= (1 << i);
            if(sum < h) continue;
            ans += dp[task];
        }
        prcas; printf("%lld\n", ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/163467wyj/p/11728925.html

时间: 2024-08-30 18:24:04

Round G 2019 - Kick Start 2019的相关文章

Kick Start 2019 - Round A A.Training 题解

题意 n个数中选出一组K个数,要求这一组数中所有数与这组数中最大值的差之和最小. 思路 很容易想到排序构造单调性,很容易想到利用前缀和降低复杂度. 把题意翻译成数学语言就是: $\sum_{j=i}^{i+K-1}a[i] - a[j] $ $=K*a[i] -\sum_{j=i}^{i+K-1}a[j]$ $=K*a[i]-(s[i+K-1]-s[i-1])?$ 化简式子之后就可以线性做了. 代码 1 #define inf 1000000000 2 int n,K; 3 LL a[N]; 4

【DP 好题】Kick Start 2019 Round C Catch Some

题目链接 题目大意 在一条数轴上住着 $N$ 条狗和一个动物研究者 Bundle.Bundle 的坐标是 0,狗的坐标都是正整数,可能有多条狗住在同一个位置.每条狗都有一个颜色.Bundle 需要观测 $K$ 条狗.要观测一条狗 Bundle 必须走到狗的住处,并且穿着和狗同色的衣服.Bundle 只能在家换衣服.试问 Bundle 至少要走多长的路程?注意:最后 Bundle 不必回到住处. Constraints 不超过 100 组测试数据 $ 1 \le N \le 1000 $ $ 1

Kick Start 2019 Round A Parcels

题目大意 $R \times C$ 的网格,格子间的距离取曼哈顿距离.有些格子是邮局.现在可以把至多一个不是邮局的格子变成邮局,问每个格子到最近的邮局的曼哈顿距离的最大值最小是多少. 数据范围 $ 1 \le R \le 250 $ $ 1 \le C \le 250 $ 100 组测试数据 Time limit: 15 s 分析 显然可以二分答案. 几何视角 考虑平面上的整点(也称格点).到一个格点的曼哈顿距离不大于 $k$ 的所有格点的轮廓是一个旋转了 45° 的正方形( For any p

WPS 2019|WPS Office 2019官方最新版 v11.1下载

点击下载WPS Office 2019官方最新版WPS 2019是一款由金山软件公司自主研发并推出的最新办公软件套装,而作为目前来说最新的版本,其无论是在功能上还是在本身的系统优化上都得到前所未有的加强,还带来了全新的用户界面,绝对会让摆脱旧版界面的审美疲劳,给你焕然一新的感觉!同时还将wps文字,wps演示,wps表格合而为一,消除了组件隔阂,现在用户只需在一个窗口下就可以打开doc\xls\ppt文件,不必先寻找对应组件, 再切换文档标签,非常便捷!不仅如此,WPS 2019还加强了标签管理

【 Ex 2019 】 WinSrv 2019 安裝 Ex 2019

由於這個是測試環境,你還是需要準備:IP段.域名等. 1.Windows Server 2019 創建 域(略)其實跟Windows Server 2016的方法一致,有時間我會再做一個教程出來. 2.下載 Exchange 2019(體驗版)http://blog.51cto.com/happynews/2153851 3.客戶端加入 域(略)其實跟你以往的經驗一致,有時間我會再做一個. 4.管理員啟動PowerShell 5.運行IIS的安裝命令( Install-WindowsFeatur

jzoj5990. 【北大2019冬令营模拟2019.1.6】Bear (状压dp)

题面 题解 我永远讨厌dp.jpg 搞了一个下午优化复杂度最后发现只要有一个小trick就可以A了→_→.全场都插头dp就我一个状压跑得贼慢-- 不难发现我们可以状压,对于每一行,用状态\(S\)表示有哪些格子是已经被上一行推倒了的,那么我们可以枚举本行所有格子的字母情况,然后计算一下这个时候下一行格子被推倒的情况,把这一行的贡献加到下一行就行了. 简单来说就是记一个\(f[pos][S]\)表示第\(pos\)行,格子被推倒的情况为\(S\)时的方案数,\(dp[pos][S]\)为所有方案中

【 Ex 2019 】 WinSrv 2019 安裝 Ex 2019(二)

1.Install-WindowsFeature RSAT-ADDS2.利用Exchange擴展AD架構,從Exchange2013開始,我發現只要通過UI的嚮導去拓展這個AD架構是100%失敗,所以微軟公司的產品,還是好大的Bug,直接差評,哈哈哈哈,好吧,我們直接PowerShell吧!( .\Setup.exe /PrepareSchema /IAcceptExchangeServerLicenseTerms )Done3.( .\setup /IAcceptExchangeServerL

【 Ex 2019 】 WinSrv 2019 安裝 Ex 2019(三)

1.插入Exchange2019的ISO文件,直接雙擊2.由於是測試環境,我們選擇不更新,下一步3.4.下一步5.同意,下一步6.默認,下一步7.黃色標記,下一步(由於我只有一台AD,所以直接選擇這兩個選項,邊緣傳輸服務器,你需要部署另外一台DC才可以,其實微軟公司是不建議我們AD上安裝任何的東西,由於是測試環境,無所謂啦~)8.默認下一步9.否,下一步(因為我的虛擬機沒有設置連接外網,所以不選擇這個)10.安裝11.檢查結果12.正式開始安裝,這個過程就要看你的硬件配置了--13.我以為它掛了

jzoj5991. 【北大2019冬令营模拟2019.1.6】Juice

题面 题解 好迷-- //minamoto #include<bits/stdc++.h> #define R register #define ll long long #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i) #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i) #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)