問題
http://community.topcoder.com/stat?c=problem_statement&pm=1786&rd=4590
サラリーマンは出社したときと退社した時にスタンプカードを押し、その時間がわかっている。ただし、退社した時の時間は仕事時間に含まれない。
合わせて時給がわかっており、0:00~5:59の間、かつ18:00~23:59の間は時給が1.5倍になる。
このとき、サラリーマンの一日の給料を求める。
ただし、小数点以下は切り下げる。
解き方
シミュレーション問題なので以下にシンプルに実装するか。
同じ計算は記載ミスを招くので、2度以上現れる計算は変数に保存して扱うことでミスをより少なくできる。
コード
using namespace std;
#define all(c) (c).begin(),(c).end()
#define FORE(i,d,e) for(int i=d;i<e;i++)
#define FOR(i,s,e) for (int i = int(s); i != int(e); i++)
#define FORIT(i,c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ISEQ(c) (c).begin(), (c).end()
class Salary {
public:
int calc(string str){
int h=(str[0]-'0')*10+(str[1]-'0');
int m=(str[3]-'0')*10+(str[4]-'0');
int s=(str[6]-'0')*10+(str[7]-'0');
return h*3600+m*60+s;
}
int howMuch(vector<string> arrival, vector<string> departure, int wage) {
double ret=0.0;
FORE(i,0,arrival.size()){
int start=calc(arrival[i]);
int end=calc(departure[i])-1;
int s1=max(min(end,21599)-max(start,0)+1,0);
int s2=max(min(end,64799)-max(start,21600)+1,0);
int s3=max(min(end,86399)-max(start,64800)+1,0);
ret+=s1*1.5+s2+s3*1.5;
}
return (int)(ret*wage/3600);
}
};
#define all(c) (c).begin(),(c).end()
#define FORE(i,d,e) for(int i=d;i<e;i++)
#define FOR(i,s,e) for (int i = int(s); i != int(e); i++)
#define FORIT(i,c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ISEQ(c) (c).begin(), (c).end()
class Salary {
public:
int calc(string str){
int h=(str[0]-'0')*10+(str[1]-'0');
int m=(str[3]-'0')*10+(str[4]-'0');
int s=(str[6]-'0')*10+(str[7]-'0');
return h*3600+m*60+s;
}
int howMuch(vector<string> arrival, vector<string> departure, int wage) {
double ret=0.0;
FORE(i,0,arrival.size()){
int start=calc(arrival[i]);
int end=calc(departure[i])-1;
int s1=max(min(end,21599)-max(start,0)+1,0);
int s2=max(min(end,64799)-max(start,21600)+1,0);
int s3=max(min(end,86399)-max(start,64800)+1,0);
ret+=s1*1.5+s2+s3*1.5;
}
return (int)(ret*wage/3600);
}
};