65,186
社区成员




//实现一个函数:求数轴上多个线段覆盖的区域对应的多个线段; 输入多个线段,求出被这些线段覆盖的所有区域(也用线段表示); 一条线段用两个值表示(x0,x1), 其中x1>x0;
//比如(1,3);(2,4);(5,6);结果为(1,4);(5,6);
//比如(1,3);(2,4);(5,6);(4,7);结果为(1,7);
#include <stdio.h>
#define MAXLINES 100
struct LINE {
int x0;//左端
int x1;//右端
} ls[MAXLINES];
int i,j,k,n,x0,x1,c;
void add() {
if (0==n) {//加入第一对点
ls[n].x0=x0;
ls[n].x1=x1;
n=1;
} else {
if (x1==ls[0].x0) {//右端=第一条线段的左端
ls[0].x0=x0;//第一条线段的左端修改为左端
return;
}
if (x1<ls[0].x0) {//右端<第一条线段的左端
for (i=n-1;i>=0;i--) {//将所有线段往后移
ls[i+1].x0=ls[i].x0;
ls[i+1].x1=ls[i].x1;
}
ls[0].x0=x0;//新第一条线段为x0,x1
ls[0].x1=x1;
n++;
return;
}
if (ls[n-1].x1<x0) {//左端>最后那条线段的右端
ls[n].x0=x0;//新最后那条线段
ls[n].x1=x1;
n++;
return;
}
if (x0<=ls[0].x0 && ls[n-1].x1<=x1) {//左端≤第一条线段的左端且最后那条线段的右端≤右端
ls[0].x0=x0;//只剩这一条线段
ls[0].x1=x1;
n=1;
return;
}
for (i=0;i<n;i++) {//从左到右依次检查每条线段
if (ls[i].x0<=x0 && x0<=ls[i].x1) {//第i条线段的左端≤左端≤第i条线段的右端
for (j=i;j<n;j++) {//从第i条线段开始从左到右依次检查每条线段
if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端
ls[i].x1=ls[j].x1;//第i条线段的右端改为第j条线段的右端
for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
ls[i+k].x0=ls[j+k].x0;
ls[i+k].x1=ls[j+k].x1;
}
n-=j-i;
return;
}
if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端<右端<第j+1条线段的左端(如果有)
ls[i].x1=x1;//第i条线段的右端改为右端
for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
ls[i+k].x0=ls[j+k].x0;
ls[i+k].x1=ls[j+k].x1;
}
n-=j-i;
return;
}
}
}
if (ls[i].x1<x0 && (i==n-1 || x0<ls[i+1].x0)) {//第i条线段的右端<左端<第i+1条线段的左端(如果有)
if (i!=n-1 && x1<ls[i+1].x0) {//右端<第i+1条线段的左端(如果有)
for (k=n-1;k>=i+1;k--) {//将从第i+1条线段开始的所有线段往后移
ls[k+1].x0=ls[k].x0;
ls[k+1].x1=ls[k].x1;
}
ls[i+1].x0=x0;//新第i+1条线段为x0,x1
ls[i+1].x1=x1;
n++;
return;
}
for (j=i+1;j<n;j++) {//从第i+1条线段开始从左到右依次检查每条线段
if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端
ls[i+1].x0=x0;//第i+1条线段的左端改为左端
ls[i+1].x1=ls[j].x1;//第i+1条线段的右端改为第j条线段的右端
for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
ls[i+1+k].x0=ls[j+k].x0;
ls[i+1+k].x1=ls[j+k].x1;
}
n-=j-i-1;
return;
}
if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端<右端<第j+1条线段的左端(如果有)
ls[i+1].x0=x0;//第i+1条线段的左端改为左端
ls[i+1].x1=x1;//第i+1条线段的右端改为右端
for (k=1;k<n-j-1;k++) {//将剩余线段往前移
ls[i+k].x0=ls[j+k].x0;
ls[i+k].x1=ls[j+k].x1;
}
n-=j-i-1;
return;
}
}
}
if (x0<ls[i].x0) {//左端<第i条线段的左端
for (j=i;j<n;j++) {//从第i条线段开始从左到右依次检查每条线段
if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端
ls[i].x0=x0;//第i条线段的左端改为左端
ls[i].x1=ls[j].x1;//第i条线段的右端改为第j条线段的右端
for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
ls[i+k].x0=ls[j+k].x0;
ls[i+k].x1=ls[j+k].x1;
}
n-=j-i;
return;
}
if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端<右端<第j+1条线段的左端(如果有)
ls[i].x0=x0;//第i条线段的左端改为左端
ls[i].x1=x1;//第i条线段的右端改为右端
for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
ls[i+k].x0=ls[j+k].x0;
ls[i+k].x1=ls[j+k].x1;
}
n-=j-i;
return;
}
}
}
}
}
}
void show() {
for (i=0;i<n;i++) {
printf("(%d,%d);",ls[i].x0,ls[i].x1);
}
printf("\n");
}
void main() {
n=0;
c=0;
while (1) {
printf("Input x0,x1(x0<x1;0,0 to exit):");
fflush(stdout);
rewind(stdin);
if (2==scanf("%d,%d",&x0,&x1)) {
if (0==x0&&0==x1) break;
if (x1>x0) {
c++;
if (c>=MAXLINES) {
printf("Up to %d!\n",MAXLINES);
break;
}
add();
show();
}
}
}
}
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <list>
using namespace std;
enum Action
{
Ask = 1,
Free,
};
bool EQ(const pair <Action , int > &in )
{
if(in.first == Ask)
return true;
return false;
}
struct QMC
{
int mIndex; // Machine index
int coreLeft; // in fact left cores
int coreStart; // last left
bool operator == ( const QMC & in) const
{
if(mIndex == in.mIndex && coreLeft == in.coreLeft && coreStart == in.coreStart)
{
return true;
}
return false;
}
};
void PR(const QMC &in )
{
if(in.mIndex > 0)
cout << in.mIndex << ' ' << in.coreStart << "\r\n";
else
cout << -1 << ' ' << -1 << "\r\n";
}
struct MC
{
int mIndex;
int maxSliceCount;
list<QMC> freeList;
QMC getCores(const int size);
void insertList(const QMC &in);
};
struct cmpMCLess
{
bool operator ()(const MC *l, const MC *r) const
{
if(l->mIndex < r->mIndex)
return true;
return false;
}
};
class coresLeftBenchMark
{
private:
vector<set<MC *, cmpMCLess> > m_coresLeftBenchMark; // build 128 line for each counter query...
public:
coresLeftBenchMark(const int &size)
:m_coresLeftBenchMark( size + 1, set<MC *, cmpMCLess>() )
{
}
set<MC *, cmpMCLess>::iterator get(const int &size)
{
return m_coresLeftBenchMark[size].begin();
}
set<MC *, cmpMCLess>::iterator getEnd(const int &size)
{
return m_coresLeftBenchMark[size].end();
}
void add(MC *in);
void resize(MC *in, int fromSize, int toSize);
};
void coresLeftBenchMark ::add(MC *in )
{
for(int i = 1; i <= in->maxSliceCount; i++)
{
m_coresLeftBenchMark[i].insert(in);
}
}
void coresLeftBenchMark ::resize(MC *in, int fromSize, int toSize)
{
if(fromSize == toSize)
return;
if(fromSize < toSize)
{
for(int i = fromSize + 1; i <= toSize; i++)
{
m_coresLeftBenchMark[i].insert(in);
}
}
if(fromSize > toSize)
{
for(int i = toSize + 1; i <= fromSize; i++)
{
m_coresLeftBenchMark[i].erase(in);
}
}
}
class CMsTest
{
private:
const static int machineCoreMax = 128;
MC *mcArr;
coresLeftBenchMark m_coresLeftBenchMark; // build 128 line for each counter query...
vector<QMC> coresAsked;
vector<pair<Action, int> > actions;
public:
CMsTest()
:m_coresLeftBenchMark(machineCoreMax + 1)
{
mcArr = NULL;
}
~CMsTest()
{
delete []mcArr;
}
void init(vector<int> &in_cores, vector<pair<Action, int> > & in_actions)
{
int coreSize = in_cores.size();
mcArr = new MC[coreSize];
for(int i = 0; i < coreSize; i++)
{
QMC mc = {i + 1, in_cores[i], 1};
mcArr[i].mIndex = i + 1;
mcArr[i].maxSliceCount = in_cores[i];
mcArr[i].freeList.push_back(mc);
m_coresLeftBenchMark.add(mcArr + i);
}
coresAsked.reserve(in_actions.size()/2);
actions.swap( in_actions);
in_cores.clear();
in_actions.clear();
}
void calculate()
{
vector<pair<Action, int> >::reverse_iterator iter = find_if(actions.rbegin(), actions.rend(), EQ);
actions.erase(iter.base(), actions.end());
for(vector<pair<Action, int> >::iterator iter = actions.begin(); iter != actions.end(); iter++)
{
pair< Action, int> &i_pair = *iter;
if(i_pair.first == Ask)
{
if(i_pair.second > machineCoreMax)
{
QMC objAsk = {0};
coresAsked.push_back(objAsk);
continue;
}
set<MC*, cmpMCLess>::iterator iter = m_coresLeftBenchMark.get(i_pair.second);
if(iter != m_coresLeftBenchMark.getEnd(i_pair.second))
{
MC *pmc = *iter;
int preMax = pmc->maxSliceCount;
QMC obj = pmc->getCores(i_pair.second);
QMC objAsk = obj;
objAsk.coreLeft = i_pair.second;
coresAsked.push_back(objAsk);
m_coresLeftBenchMark.resize(pmc, preMax, pmc->maxSliceCount);
}
else
{
QMC objAsk = {0};
coresAsked.push_back(objAsk);
}
}
else
{
int mIndex = coresAsked[i_pair.second - 1].mIndex;
if(mIndex > 0)
{
MC *pmc = &mcArr[mIndex - 1];
int preMax = pmc->maxSliceCount;
pmc->insertList(coresAsked[i_pair.second - 1]);
m_coresLeftBenchMark.resize(pmc, preMax, pmc->maxSliceCount);
}
}
}
}
void outPut()
{
for_each(coresAsked.begin(), coresAsked.end(), PR);
}
};
int main()
{
int testCount = 0;
cin >> testCount;
if(testCount < 1 || testCount > 20)
return 0;
CMsTest *memTest = new CMsTest[testCount];
vector<int> cores;
vector<pair<Action, int> > query;
for(int i = 0; i < testCount; i++)
{
int M, Q;
cin >> M >> Q;
cores.reserve(M);
query.reserve(Q);
while(M--)
{
int C;
cin >> C;
cores.push_back(C);
}
while(Q--)
{
int C;
string act;
cin >> act >> C;
if(act == "A")
{
query.push_back(make_pair( Ask, C));
}
else if(act == "F")
{
query.push_back(make_pair( Free, C));
}
else
{
continue;
}
}
memTest[i].init(cores, query);
memTest[i].calculate();
}
for(int i = 0; i < testCount; i++)
{
cout << "Case #" << i + 1 << ":\r\n";
memTest[i].outPut();
}
delete []memTest;
return 0;
}
QMC MC::getCores(const int size)
{
int tempCount = 0;
QMC obj;
for(list<QMC>::iterator iter = freeList.begin(); iter != freeList.end(); iter++)
{
if(iter->coreLeft >= size)
{
obj = *iter;
tempCount = iter->coreLeft;
iter->coreLeft -= size;
iter->coreStart += size;
if(iter->coreLeft == 0)
{
freeList.erase(iter);
}
break;
}
}
if(tempCount >= maxSliceCount)
{
int max = 0;
for(list<QMC>::iterator iter = freeList.begin(); iter != freeList.end(); iter++)
{
if(iter->coreLeft > max)
{
max = iter->coreLeft;
}
}
maxSliceCount = max;
}
return obj;
}
void MC::insertList(const QMC &in)
{
if(freeList.empty())
{
freeList.push_back(in);
maxSliceCount = in.coreLeft;
return;
}
for(list<QMC>::iterator iter = freeList.begin(); iter != freeList.end(); iter++)
{
if(in.coreStart < iter->coreStart)
{
list< QMC>:: iterator insIter = freeList.insert(iter, in);
list< QMC>:: iterator insIterTemp = insIter;
list< QMC>:: iterator cIter = insIter;
list< QMC>:: iterator nIter = ++insIter;
QMC prv = {0, 0, 0};
QMC cur = *cIter;
QMC nxt = {0, 0, 0};
if(cIter != freeList.begin())
prv = *--insIterTemp;
if(nIter != freeList.end())
nxt = *nIter;
if( prv.coreStart + prv.coreLeft == cur.coreStart &&
cur.coreStart + cur.coreLeft == nxt.coreStart)
{
freeList.erase(nIter);
freeList.erase(cIter);
prv.coreLeft += (cur.coreLeft + nxt.coreLeft);
insIterTemp->coreLeft = prv.coreLeft;
if(insIterTemp->coreLeft > maxSliceCount)
{
maxSliceCount = insIterTemp->coreLeft;
}
}
else if( prv.coreStart + prv.coreLeft == cur.coreStart)
{
freeList.erase(cIter);
prv.coreLeft += cur.coreLeft;
insIterTemp->coreLeft = prv.coreLeft;
if(insIterTemp->coreLeft > maxSliceCount)
{
maxSliceCount = insIterTemp->coreLeft;
}
}
else if(cur.coreStart + cur.coreLeft == nxt.coreStart)
{
freeList.erase(nIter);
cur.coreLeft += nxt.coreLeft;
cIter->coreLeft = cur.coreLeft;
if(cIter->coreLeft > maxSliceCount)
{
maxSliceCount = cIter->coreLeft;
}
}
break;
}
}
}