2007B
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[07年度-ACM-ICPC国内予選]]
***2007B [#z72a2ab6]
-''Blue Screenの解答''
回答者:[[七星(PLOW)]]&br;
所要時間:55分&br;
予選時:クリア/1ミス
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <conio.h>
class CData
{
public:
CData();
bool Login(int, int, int);
bool Logout(int, int);
int Output(int , int, int);
void Combine(CData*);
int student;
int PC;
int BeginTime;
int EndTime;
};
void CData::Combine(CData *pDat)
{
if(EndTime == 0)
{
return;
}
if(pDat->student == student)
{
if(pDat->BeginTime < EndTime )
{
if(pDat->EndTime > EndTime)
{
EndTime = pDat->EndTime;
}
pDat->EndTime = 0;
}
}
}
int CData::Output(int time, int time2, int stu)
{
int bo;
if(EndTime <= 0)
{
return 0;
}
if(stu != student)
{
return 0;
}
if(time < BeginTime)
{
if(time2 > EndTime)
{
return (EndTime - BeginTime);
}
else
{
bo = time2 - BeginTime;
if(bo > 0)
{
return bo;
}
return 0;
}
}
else if(time2 < BeginTime || time > EndTime)
{
return 0;
}
else if(time > BeginTime && time2 < EndTime)
{
return (time2 - time);
}
else
{
if(time2 > EndTime)
{
return (EndTime - time);
}
else
{
bo = EndTime - time;
if(bo > 0)
{
return bo;
}
return 0;
}
}
return 0;
}
CData::CData()
{
memset(this, 0, sizeof(CData));
PC = -1;
}
bool CData::Login(int time, int pc, int stu)
{
if(BeginTime != 0)
{
return false;
}
PC = pc;
BeginTime = time;
student = stu;
return true;
}
bool CData::Logout(int time, int pc)
{
if(EndTime != 0)
{
return false;
}
if(PC == pc)
{
EndTime = time;
return true;
}
return false;
}
int main()
{
//ファイル処理-----------------
char FileName[256];
printf("ファイル名を入れて〜");
scanf("%256s", FileName);
FILE* fpIn = fopen(FileName, "r");
FILE* fpOut = fopen("output.txt", "w");
//-----------------------------
int PCNum, StuNum, DatNum;
int Time, PC, Student, bo, QNum, total;
CData* pDat;
while(1)
{
fscanf(fpIn, "%d %d", &PCNum, &StuNum);
if(PCNum == 0 && StuNum == 0)
{
break;
}
fscanf(fpIn, "%d", &DatNum);
//データ読み込み
pDat = new CData[DatNum];
for(int i = 0; i < DatNum;i++)
{
fscanf(fpIn,"%d %d %d %d", &Time, &PC, &Student, &bo);
if(bo)
{
for(int k = 0;k < DatNum;k++)
{
if(pDat[k].Login(Time, PC, Student))
{
break;
}
}
}
else
{
for(int k = 0;k < DatNum;k++)
{
if(pDat[k].Logout(Time, PC))
{
break;
}
}
}
}
//質問処理
for(int i = 0;i < DatNum;i++)
{
for(int k = i + 1;k < DatNum;k++)
{
pDat[i].Combine(&pDat[k]);
}
}
fscanf(fpIn,"%d", &QNum);
for(int i = 0;i < QNum;i++)
{
fscanf(fpIn,"%d %d %d", &Time, &PC, &Student);
total = 0;
for(int k = 0;k < DatNum;k++)
{
total += pDat[k].Output(Time, PC, Student);
}
fprintf(fpOut, "%d\n", total);
}
delete [] pDat;
}
//終了処理---------------------
fclose(fpOut);
printf("終了!");
getch();
return 0;
}
--解説&br;
CDataクラスを作成し各PCの使用記録を保存してから、&br;
同じ生徒が複数のPCを重なる時間帯に使用していた場合は1つのデータに結合する事で&br;
各生徒の連続使用毎の使用記録にした。&br;
その後、このCDataから各質問に対応する結果を出力させた。&br;
&br;
出力の際の場合分けが若干複雑。&br;
-''include studioの解答''&br;
回答者:[[CISC]]&br;
所要時間:160分+20分&br;
予選時:ドボン
#include <stdio.h>
FILE *fp_in, *fp_out;
static char *f_source = "B_in.txt";
static char *f_answer = "B_out.txt";
struct DATA{
int t,n,m,s;
};
int main(void)
{
int maxStu,maxPC,maxData,maxQue,time;
struct DATA data[1001];
int qts,qte,qm;
int i,j,k;
int cntLogIn,logInTime;
fp_in = fopen(f_source, "r");
fp_out = fopen(f_answer, "w");
while(1)
{
fscanf(fp_in, "%d %d ",&maxPC,&maxStu);
//終了条件確認
if(maxPC==0 && maxStu==0) break;
fscanf(fp_in, "%d ",&maxData);
//利用記録読み込み
for(i=0;i<maxData;i++)
{
fscanf(fp_in, "%d %d %d %d ",
&(data[i].t) ,&(data[i].n) ,&(data[i].m) ,&(data[i].s));
}
//質問読み込み確認
fscanf(fp_in , "%d ",&maxQue);
for(i=0;i<maxQue;i++)
{
//読み込み
fscanf(fp_in, "%d %d %d ",
&(qts) ,&(qte) ,&(qm) );
//確認作業
time=0;cntLogIn=0;
for(k=0;k<maxData;k++)
{//利用記録から学生を検索
if(data[k].m == qm)
{//記録に該当する学生がいた場合
if(data[k].s==1)
{//ログインしたとき
if(cntLogIn==0)
{
logInTime=data[k].t;
}
cntLogIn++;
}
else
{//ログアウトしたとき
cntLogIn--;
if(cntLogIn==0)
{
if(qts>data[k].t || qte<logInTime)
{
;
}
else if(qts>=logInTime && data[k].t>=qte)
{
time+=qte-qts;
}
else if(qts<=logInTime && data[k].t<=qte)
{
time+=data[k].t-logInTime;
}
else if(qts>=logInTime && data[k].t<=qte)
{
time+=data[k].t-qts;
}
else if(qts<=logInTime && data[k].t>=qte)
{
time+=qte-logInTime;
}
}
}
}
}
fprintf(fp_out, "%d\n",time);
}
}
fclose(fp_in);
fclose(fp_out);
return 0;
}
--解説(言い訳)&br;
B問題ごときに160分かけてしまった私です。今日20分ほどで解決しました。。&br;
原因は、ズバリ「問題読み間違え」です。延べ利用時間じゃなかったんですね・・・。&br;
プログラムの解説は、まあ特に言うこともないのですが、順を追って処理し、&br;
重複ログインはカウントの増減で判断しています。&br;
多分それ以外には書くほどのこともないかなぁと。&br;
ちなみに、不正なデータがあるとこいつは処理できません。&br;
終了行:
[[07年度-ACM-ICPC国内予選]]
***2007B [#z72a2ab6]
-''Blue Screenの解答''
回答者:[[七星(PLOW)]]&br;
所要時間:55分&br;
予選時:クリア/1ミス
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <conio.h>
class CData
{
public:
CData();
bool Login(int, int, int);
bool Logout(int, int);
int Output(int , int, int);
void Combine(CData*);
int student;
int PC;
int BeginTime;
int EndTime;
};
void CData::Combine(CData *pDat)
{
if(EndTime == 0)
{
return;
}
if(pDat->student == student)
{
if(pDat->BeginTime < EndTime )
{
if(pDat->EndTime > EndTime)
{
EndTime = pDat->EndTime;
}
pDat->EndTime = 0;
}
}
}
int CData::Output(int time, int time2, int stu)
{
int bo;
if(EndTime <= 0)
{
return 0;
}
if(stu != student)
{
return 0;
}
if(time < BeginTime)
{
if(time2 > EndTime)
{
return (EndTime - BeginTime);
}
else
{
bo = time2 - BeginTime;
if(bo > 0)
{
return bo;
}
return 0;
}
}
else if(time2 < BeginTime || time > EndTime)
{
return 0;
}
else if(time > BeginTime && time2 < EndTime)
{
return (time2 - time);
}
else
{
if(time2 > EndTime)
{
return (EndTime - time);
}
else
{
bo = EndTime - time;
if(bo > 0)
{
return bo;
}
return 0;
}
}
return 0;
}
CData::CData()
{
memset(this, 0, sizeof(CData));
PC = -1;
}
bool CData::Login(int time, int pc, int stu)
{
if(BeginTime != 0)
{
return false;
}
PC = pc;
BeginTime = time;
student = stu;
return true;
}
bool CData::Logout(int time, int pc)
{
if(EndTime != 0)
{
return false;
}
if(PC == pc)
{
EndTime = time;
return true;
}
return false;
}
int main()
{
//ファイル処理-----------------
char FileName[256];
printf("ファイル名を入れて〜");
scanf("%256s", FileName);
FILE* fpIn = fopen(FileName, "r");
FILE* fpOut = fopen("output.txt", "w");
//-----------------------------
int PCNum, StuNum, DatNum;
int Time, PC, Student, bo, QNum, total;
CData* pDat;
while(1)
{
fscanf(fpIn, "%d %d", &PCNum, &StuNum);
if(PCNum == 0 && StuNum == 0)
{
break;
}
fscanf(fpIn, "%d", &DatNum);
//データ読み込み
pDat = new CData[DatNum];
for(int i = 0; i < DatNum;i++)
{
fscanf(fpIn,"%d %d %d %d", &Time, &PC, &Student, &bo);
if(bo)
{
for(int k = 0;k < DatNum;k++)
{
if(pDat[k].Login(Time, PC, Student))
{
break;
}
}
}
else
{
for(int k = 0;k < DatNum;k++)
{
if(pDat[k].Logout(Time, PC))
{
break;
}
}
}
}
//質問処理
for(int i = 0;i < DatNum;i++)
{
for(int k = i + 1;k < DatNum;k++)
{
pDat[i].Combine(&pDat[k]);
}
}
fscanf(fpIn,"%d", &QNum);
for(int i = 0;i < QNum;i++)
{
fscanf(fpIn,"%d %d %d", &Time, &PC, &Student);
total = 0;
for(int k = 0;k < DatNum;k++)
{
total += pDat[k].Output(Time, PC, Student);
}
fprintf(fpOut, "%d\n", total);
}
delete [] pDat;
}
//終了処理---------------------
fclose(fpOut);
printf("終了!");
getch();
return 0;
}
--解説&br;
CDataクラスを作成し各PCの使用記録を保存してから、&br;
同じ生徒が複数のPCを重なる時間帯に使用していた場合は1つのデータに結合する事で&br;
各生徒の連続使用毎の使用記録にした。&br;
その後、このCDataから各質問に対応する結果を出力させた。&br;
&br;
出力の際の場合分けが若干複雑。&br;
-''include studioの解答''&br;
回答者:[[CISC]]&br;
所要時間:160分+20分&br;
予選時:ドボン
#include <stdio.h>
FILE *fp_in, *fp_out;
static char *f_source = "B_in.txt";
static char *f_answer = "B_out.txt";
struct DATA{
int t,n,m,s;
};
int main(void)
{
int maxStu,maxPC,maxData,maxQue,time;
struct DATA data[1001];
int qts,qte,qm;
int i,j,k;
int cntLogIn,logInTime;
fp_in = fopen(f_source, "r");
fp_out = fopen(f_answer, "w");
while(1)
{
fscanf(fp_in, "%d %d ",&maxPC,&maxStu);
//終了条件確認
if(maxPC==0 && maxStu==0) break;
fscanf(fp_in, "%d ",&maxData);
//利用記録読み込み
for(i=0;i<maxData;i++)
{
fscanf(fp_in, "%d %d %d %d ",
&(data[i].t) ,&(data[i].n) ,&(data[i].m) ,&(data[i].s));
}
//質問読み込み確認
fscanf(fp_in , "%d ",&maxQue);
for(i=0;i<maxQue;i++)
{
//読み込み
fscanf(fp_in, "%d %d %d ",
&(qts) ,&(qte) ,&(qm) );
//確認作業
time=0;cntLogIn=0;
for(k=0;k<maxData;k++)
{//利用記録から学生を検索
if(data[k].m == qm)
{//記録に該当する学生がいた場合
if(data[k].s==1)
{//ログインしたとき
if(cntLogIn==0)
{
logInTime=data[k].t;
}
cntLogIn++;
}
else
{//ログアウトしたとき
cntLogIn--;
if(cntLogIn==0)
{
if(qts>data[k].t || qte<logInTime)
{
;
}
else if(qts>=logInTime && data[k].t>=qte)
{
time+=qte-qts;
}
else if(qts<=logInTime && data[k].t<=qte)
{
time+=data[k].t-logInTime;
}
else if(qts>=logInTime && data[k].t<=qte)
{
time+=data[k].t-qts;
}
else if(qts<=logInTime && data[k].t>=qte)
{
time+=qte-logInTime;
}
}
}
}
}
fprintf(fp_out, "%d\n",time);
}
}
fclose(fp_in);
fclose(fp_out);
return 0;
}
--解説(言い訳)&br;
B問題ごときに160分かけてしまった私です。今日20分ほどで解決しました。。&br;
原因は、ズバリ「問題読み間違え」です。延べ利用時間じゃなかったんですね・・・。&br;
プログラムの解説は、まあ特に言うこともないのですが、順を追って処理し、&br;
重複ログインはカウントの増減で判断しています。&br;
多分それ以外には書くほどのこともないかなぁと。&br;
ちなみに、不正なデータがあるとこいつは処理できません。&br;
ページ名: