1. 程式人生 > >[尺取法]2017 ACM/ICPC Asia Regional Shenyang Online 1012

[尺取法]2017 ACM/ICPC Asia Regional Shenyang Online 1012

更正一下,原來的程式碼用的結構體,比賽時記憶體卡過去了,現在改成陣列,時間記憶體都減少了。謝謝!@小白c
比賽時的提交:
比賽是的提交
修正後:
修正後

題目:
這裡寫圖片描述
這裡寫圖片描述

題意&分析:
題目的意思大概就是對於 n 堆卡牌,每堆 ai 張,對應的取了這堆的所有牌到手上之後要翻牌子(臣妾做不到),翻 bi 張,當手上的牌不夠翻的時候,遊戲結束,拿走在手上的所有牌(不管翻沒翻),遊戲開始前可以將最前面一堆移到最後面(次數不限),求可以拿走牌的最大值。

設已經那的牌的個數是maxa,要翻的牌總數是maxb,
等價轉換成
1. maxa>=maxb,那麼就可以繼續取;
2. maxa < maxb,遊戲結束;

用尺取法,對於要移動堆這件事,可以輸入資料的時候就在後面複製一邊(e.g. 1234512345)。

尺取法介紹: 一號傳送門 二號傳送門

程式碼如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map> #include <queue> #include <set> #include <stack> #include <string> #include <cctype> #include <fstream> #define INF 0x3f3f3f3f #define TEST cout<<"stop here"<<endl using namespace std; typedef long long ll; const ll mod = 1e9 + 7; const
ll maxn = 2e6 + 7; /* struct node { ll a,b; }m[maxn]; */ int a[maxn],b[maxn]; int main(){ std::ios::sync_with_stdio(false); std::cin.tie(0); ll n; while(cin>>n){ ll i, j; for(i=1;i<=n;i++){ cin>>a[i]; a[i+n] = a[i]; } for(i=1;i<=n;i++){ cin>>b[i]; b[i+n]= b[i]; } ll mov = 0,cnt = 0,maxa = 0,maxb = 0,temp = 0; i = 1,j = 1; while(true){ while(maxa>=maxb && j-i+1<=n){ maxa += a[j]; maxb += b[j]; j++; } if(temp<maxa){ temp = maxa; mov = i; } if(maxa==maxb || (i>n && j>2*n-1))break; maxa -= a[i]; maxb -= b[i]; i++; } cout<< mov - 1 <<endl; } return 0; }