[[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,maxRiyou,maxQue,time;
    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 ",&maxRiyou);
        fscanf(fp_in, "%d ",&maxData);
        
        //利用記録読み込み
        for(i=0;i<maxRiyou;i++)
        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<maxRiyou;k++)
            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;

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS