USACO的第二道题一开始不是很会做,但是,经过分析后,发现其实这道题就是一个边读入边计算的题目,用个结构体把人的名字,支出,收入框起来就行了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <ctime>
using namespace std;
struct gift{
char name[15];
int pay;
int income;
}gift1[105];
int n=0;
int found(char * s){
int k=0;
for (int j=0;j<n;j++){
if (!strcmp(s,gift1[j].name)){
k=j;
break;
}
}
return k;
}
int main (){
freopen("gift1.in10","r",stdin);
freopen("gift1.out10","w",stdout);
char s[15];
int m=0,nn=0,pay[15],income[15];
memset(pay,0,sizeof(pay));
memset(income,0,sizeof(income));
int i=0,j=0,k=0,t=0,a=0,b=0;
cin>>n;
for (i=0;i<n;i++){
scanf("%s",gift1[i].name);
}
for (i=0;i<n;i++){
scanf("%s",s);
cin>>m>>nn;
if (m==0){
for (j=0;j<nn;j++){
scanf("%s",s);
}
continue;
}
k=found(s);
gift1[k].pay=m;
m/=nn;
gift1[k].income+=gift1[k].pay-m*nn;
for (a=0;a<nn;a++){
scanf("%s",s);
t=found(s);
gift1[t].income+=m;
}
}
for (i=0;i<n;i++){
cout<<gift1[i].name<<" "<<gift1[i].income-gift1[i].pay<<endl;
}
printf("time=%.2f\n",(double)clock() / CLOCKS_PER_SEC);
return 0;
}
然而,通过分析可发现,这样写的时间复杂度是O(n3),看了题解后,采用hash,即用一个map简化程序,使时间复杂度变为O(n2)。
#include <map>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
string names[15];
map<string,int> mymap;
int main (){
freopen("gift1.in","r",stdin);
freopen("gift1.out","w",stdout);
int n=0,tot=0,num=0,m=0;
string giver,reciever;
int i=0,j=0;
cin>>n;
for (i=0;i<n;i++){
cin>>names[i];
mymap[names[i]]=0;
}
while(cin>>giver>>tot>>num){
if (num==0){
continue;
}
m=tot/num;
mymap[giver] += (tot-(m*num))-tot;
for (j=0;j<num;j++){
cin>>reciever;
mymap[reciever] += m;
}
}
for (i=0;i<n;i++){
cout<<names[i]<<" "<<mymap[names[i]]<<endl;
}
}