250pt:
对普通nim游戏的改编,取石子的时候只能从前往后取,每次取非空的石子,不能取者为输。
我是从后往前推的,注意当前数字如果>1,不管后面是必胜态还是必败态,肯定能调节成必胜态,如果=1,就身不由己了。。
500pt
一开始,你有n个工厂,k个专家,每工作一轮,能获得n*k的gold,购买一个工厂或者一个专家需要price的gold,你想要获得的gold是target,当你具备足够的钱买一个专家或者工厂的时候,你可以买任意多个专家或工厂。问你最小需要几轮才能获得target的gold。
这是一个 看似难写,实则更难写的模拟题。。
注意到n k肯定是越接近越好,还有当前如果要买一个专家或者工厂,那肯定是花所有的钱去买(n,k肯定是越早增大越好)。因为下一轮就赚回来了。还有就是假设当前的钱>=price了,就需要先判断一下是不是要买工厂或者专家了,因为有可能凭借当前的nk,很快就能到达target了。
代码写的比较渣,错了很多遍
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <sstream>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
typedef long long lld;
class StrongEconomy {
public:
lld ABS(lld a)
{
if(a > 0) return a;
return -a;
}
void get(lld &n,lld &k,lld &tim) {
if(tim >= ABS(n-k) )
{
lld tn = n , tk = k;
n = (tn+tk+tim) / 2;
k = (tn+tk+tim+1) / 2;
}
else
{
if(n>k) k+=tim; else n+=tim;
}
}
lld gao(lld n,lld k,lld price,lld target,lld earn) {
lld tim = earn / price;
earn -= tim * price;
get(n,k,tim);
lld tmp = mul(n,k);
if(tmp == -1) return tmp;
lld ans = (target - earn)/tmp;
if((target-earn)%tmp) ans ++;
return ans;
}
lld mul(lld a,lld b) {
lld ans = 0;
bool flag = false;
for(int i=0; i<50; i++) {
// cout<<ans<<endl;
if(b&(1LL<<i)) {
if(flag) return -1;
ans = ans + a;
if(ans > 1000000000000LL) return -1;
}
a = a + a;
if(a > 1000000000000LL) flag = true;
}
return ans;
}
lld earn(lld n, lld k, lld price, lld target) {
if(mul(n,k) == -1) return 1;
lld round = 0;
lld earn = 0;
while(true) {
lld tmp = mul(n,k); if(tmp == -1) return round ;
// cout<<earn<<endl;
if(earn >= target) break;
if(earn >= price) {
lld tmp = mul(n,k);
lld tmp1 = (target - earn) / tmp ;
if((target-earn)%tmp) tmp1++;
lld tmp2 = gao(n,k,price,target,earn);
// cout<<tmp1<<" "<<tmp2<<endl;
if(tmp1 < tmp2 ) {
round += tmp1;
break;
} else {
lld tim = earn / price;
if(tmp2 == -1) return round + 1;
earn -= tim * price;
// cout<<"pre"<<" "<<n<<" "<<k<<" "<<tim<<endl;
get(n,k,tim);
// cout<<n<<" "<<k<<" "<<earn<<endl;
}
}
else if(price < target){
lld tmp = n * k;
lld t = (price-earn)/tmp;
if((price-earn)%tmp) t++;
round += t;
earn += t * n * k;
cout<<"earn"<<" "<<earn<<endl;
} else {
lld tmp = n * k;
lld t = (target-earn)/tmp;
if((target-earn)%tmp) t++;
round += t;
earn += t * n * k;
}
// cout<<n<<" "<<k<<endl;
}
return round;
}
// BEGIN CUT HERE
public:
void run_test(int Case) {
if ((Case == -1) || (Case == 1)) test_case_1();
}
private:
template <typename T> string print_array(const vector<T> &V) {
ostringstream os;
os << "{ ";
for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\",";
os << " }";
return os.str();
}
void verify_case(int Case, const lld &Expected, const lld &Received) {
cerr << "Test Case #" << Case << "...";
if (Expected == Received) cerr << "PASSED" << endl;
else {
cerr << "FAILED" << endl;
cerr << "\tExpected: \"" << Expected << '\"' << endl;
cerr << "\tReceived: \"" << Received << '\"' << endl;
}
}
//void test_case_0() { lld Arg0 = 4294967297LL; lld Arg1 = 4294967297LL; lld Arg2 = 1000000000000LL; lld Arg3 = 100000000000LL; lld Arg4 = 1LL; verify_case(0, Arg4, earn(Arg0, Arg1, Arg2, Arg3)); }
void test_case_1() {
lld Arg0 = 3LL;
lld Arg1 = 2LL;
lld Arg2 = 1000000000000LL;
lld Arg3 = 222LL;
lld Arg4 = 37LL;
verify_case(1, Arg4, earn(Arg0, Arg1, Arg2, Arg3));
}
// void test_case_2() { lld Arg0 = 1LL; lld Arg1 = 1LL; lld Arg2 = 500000LL; lld Arg3 = 1000002LL; lld Arg4 = 1000001LL; verify_case(2, Arg4, earn(Arg0, Arg1, Arg2, Arg3)); }
//void test_case_3() { lld Arg0 = 5LL; lld Arg1 = 4LL; lld Arg2 = 15LL; lld Arg3 = 100LL; lld Arg4 = 5LL; verify_case(3, Arg4, earn(Arg0, Arg1, Arg2, Arg3)); }
// END CUT HERE
};
// BEGIN CUT HERE
int main() {
StrongEconomy ___test;
___test.run_test(-1);
}
// END CUT HERE