// 1026.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <functional>
using namespace std;
// 单次下注记录
struct stBetInfoEx
{
int index;
int coinindex;
int coinvalue;
int coincount;
int betuserid;
};
int _testIndex(int delta)
{
static int vcoinvalue[5]={1,10,50,100,1000};
for(int i=0;i<5;i++)
{
if(delta<vcoinvalue[i])
return 2*i;
if(delta==vcoinvalue[i])
return 2*i+1;
}
return 10;
}
/*
int coin0=_testCoin(0);//0
int coin1=_testCoin(1);//1
int coin2=_testCoin(4);//1
int coin3=_testCoin(10);//10
int coin4=_testCoin(11);//10
int coin5=_testCoin(50);//50
int coin6=_testCoin(60);//50
int coin7=_testCoin(100);//100
int coin8=_testCoin(110);//100
int coin9=_testCoin(1000);//1000
int coin10=_testCoin(1100);//1000
*/
int _Index2Idx(int ret)
{
int idxs[11]={0,0,0,1,1,2,2,3,3,4,4};
int idx=idxs[ret];
return idx;
}
int _Index2Coin(int idx)
{
static int vcoinvalue[5]={1,10,50,100,1000};
int coin=vcoinvalue[idx];
return coin;
}
int _testIdx(int delta)
{
int ret=_testIndex(delta);
int idx=_Index2Idx(ret);
//cout<<"delta="<<delta<<","<<"ret="<<ret<<","<<"idx="<<idx<<endl;
return idx;
}
int _testCoin(int delta)
{
if(delta<=0)
return 0;
int idx=_testIdx(delta);
int coin=_Index2Coin(idx);
return coin;
}
int _getCoinIdx(int coin)
{
static int vcoinvalue[5]={1,10,50,100,1000};
for(int i=0;i<5;i++)
{
if(coin==vcoinvalue[i])
return i;
}
return -1;
}
// 装箱算法:返回金币面值总和不大于max,且差值要尽可能的小
// 这里的币值类型保证了先装大的,再装小的,不存在50,50,50,70,70,max=150这种类型的装箱
vector<int> _combcoin(vector<int>& vCount,int max)
{
static int vcoinvalue[5]={1,10,50,100,1000};
vector<int> v;
int sum=0;
int lastcoin=0;
while (sum<max)
{
int coin=_testCoin(max-sum);
for(int i=4;i>=0;i--)
{
if(vCount[i]==0||vcoinvalue[i]>coin)
continue;
vCount[i]--;
lastcoin=_Index2Coin(i);
sum+=lastcoin;
v.push_back(lastcoin);
break;
}
}
if(sum>max)
{
vector<int>::iterator iter=find(v.begin(),v.end(),lastcoin);
if(iter!=v.end())
{
v.erase(iter);
}
int idx=_getCoinIdx(lastcoin);
vCount[idx]++;
}
return v;
}
int gettotal(const vector<stBetInfoEx>& vIn)
{
int n=vIn.size();
int total=0;
for (int i = 0; i < n; i++)
{
stBetInfoEx ex=vIn[i];
total+=ex.coinvalue*ex.coincount;
}
return total;
}
void _dofun(vector<stBetInfoEx>& vIn,vector<int>& vDeltaCount)
{
int total=gettotal(vIn);
cout<<"total="<<total<<",";
for(int i=0;i<vDeltaCount.size();i++)
{
int coin=_Index2Coin(i);
while (vDeltaCount[i]>0)
{
for(int j=vIn.size()-1;j>=0;j--)
{
if(vIn[j].coincount==0||vIn[j].coinvalue!=coin)
continue;
int mincount=(vDeltaCount[i]<vIn[j].coincount?vDeltaCount[i]:vIn[j].coincount);
vDeltaCount[i]-=mincount;
vIn[j].coincount-=mincount;
if(vDeltaCount[i]==0)
break;
}
int a=0;
}
}
int total1=gettotal(vIn);
cout<<"total1="<<total1<<endl;
}
// 续投算法:能投多少是多少
vector<stBetInfoEx> _get_batchbet_result(const vector<stBetInfoEx>& vIn,int max)
{
vector<stBetInfoEx> vOut=vIn;
vector<int> vCount(5);
int values[5]={1,10,50,100,1000};
vector<int> vcoinvalue(5);
for(int i=0;i<5;i++)
vcoinvalue[i]=values[i];
int n=vIn.size();
int total=0;
for (int i = 0; i < n; i++)
{
stBetInfoEx ex=vIn[i];
vCount[ex.coinindex]+=ex.coincount;
total+=ex.coinvalue*ex.coincount;
}
int totalcoincount= accumulate(vCount.begin(), vCount.end(),0);
if(total<=max)
return vOut;
vector<int> vCount0=vCount;
vector<int> vcoin=_combcoin(vCount,max);
int total1= accumulate(vcoin.begin(), vcoin.end(),0);
vector<int> vNewCount(5);
for(int i=0;i<5;i++)
vNewCount[i]=vCount0[i]-vCount[i];
_dofun(vOut,vCount);
return vOut;
}
int _tmain(int argc, _TCHAR* argv[])
{
stBetInfoEx arrIn[]={
{1,1,10,4,101871},
{1,2,50,1,101871},
{1,0,1,10,101871},
{2,3,100,5,101871},
{3,3,100,5,101871},
{4,1,10,4,101871},
{4,0,1,10,101871},
};
int max1=1149;
int max2=89;
int iItemCount=sizeof(arrIn)/sizeof(arrIn[0]);
vector<stBetInfoEx> vIn(arrIn,arrIn+iItemCount);
vector<stBetInfoEx> vOut1=_get_batchbet_result(vIn,max1);
vector<stBetInfoEx> vOut11=_get_batchbet_result(vOut1,max1);
vector<stBetInfoEx> vOut2=_get_batchbet_result(vIn,max2);
vector<stBetInfoEx> vOut22=_get_batchbet_result(vOut2,max2);
system("pause");
return 0;
}