Speech Patterns
思路:建立字典查询即可。
//
// @author prime on 2017/7/1.
//
#include
#include
#include
using namespace std;
int main()
{
string input,tmp;
getline(cin,input);
map<string,int> dict;
for (int i=0;iif(isalnum(input[i]))
{
input[i]=tolower(input[i]);
tmp+=input[i];
}
else
{
if(tmp.size()>0)
{
dict[tmp]++;
}
tmp="";
}
}
if(tmp.size()>0)//注意最后一次要判断一下,不然最后的单词加不进去了。
dict[tmp]++;
int maxn=-1;
string res;
for (auto & d:dict)
{
if(d.second>maxn)
{
res=d.first;
maxn=d.second;
}
}
cout<" "<return 0;
}
Gas Station
思路:把所有居民楼和加油站都作为结点,其中加油站编号N+1开始。然后对每个加油站,运用Dijkstra求其到所有居民楼的距离,然后找到一个离所有居民楼最短距离中最远的那一个即可。顺便计算平均距离。
//
// @author prime on 2017/7/1.
//
#include
#include
using namespace std;
const int inf=99999999;
int G[1020][1020];
bool visited[1020];
int dis[1020];
int main()
{
int N,M,K,Ds;
scanf("%d%d%d%d",&N,&M,&K,&Ds);
fill(G[0],G[0]+1020*1020,inf);
for (int i=0;i//加油站编号为[N+1,
int u,v,d;
string tmp_u,tmp_v;
cin>>tmp_u>>tmp_v>>d;
if(tmp_u[0]=='G')
{
u=stoi(tmp_u.substr(1))+N;
} else
u=stoi(tmp_u);
if(tmp_v[0]=='G')
v=stoi(tmp_v.substr(1))+N;
else
v=stoi(tmp_v);
G[u][v]=d;
G[v][u]=d;
}
int res_id=-1;
double res_dis=inf,min_dis=-1;//平均距离,离居民的最近距离
for (int index=N+1;index<=N+M;++index)
{//对每个加油站求其到任意居民楼的最短距离
fill(visited,visited+1020, false);
fill(dis,dis+1020,inf);
dis[index]=0;
for (int i=1;i<=N+M;++i)
{//松弛N+M轮
int u=-1,min_d=inf;
for (int j=1;j<=N+M;j++)
{
if(dis[j]if(u==-1)
break;
visited[u]=true;
for (int v=1;v<=N+M;v++)
{
if(!visited[v]&&G[u][v]!=inf)
{
if(G[u][v]+dis[u]double tmp_dis=0,tmp_min=inf;//到所有居民的平均距离,最近距离
bool valid=true;
for (int i=1;i<=N;++i)
{
tmp_dis+=dis[i];
if(dis[i]>Ds)
{
valid=false;
break;
}
if(dis[i]if(valid)
{//这个加油站位置距离可以服务全部居民
tmp_dis/=N;
if(tmp_min>min_dis)//优先找离居民的最短距离最大的
{
res_dis=tmp_dis;
res_id=index-N;
min_dis=tmp_min;
}
else if(tmp_min==min_dis&&tmp_dis//次之找平均距离最短的
{
res_id=index-N;
res_dis=tmp_dis;
}
}
}
if(res_id==-1)
{
printf("No Solution");
return 0;
}
printf("G%d\n",res_id);
printf("%.1lf %.1lf",min_dis,res_dis);
return 0;
}
Scientific Notation
思路:和以前的科学计数法思路相近,先求指数,然后看情况补0,最后插入小数点。
//
// @author prime on 2017/7/2.
//
#include
using namespace std;
int main()
{
bool sign;
string in,res;
cin>>in;
sign= (in[0]=='+');
int exponent=0;//题目说了指数不超过9999
for (int i=1;iif(in[i]=='E')
{
exponent=stoi(in.substr(i+1));
break;
}
if(in[i]!='.')
res+=in[i];
}//res保存系数部分,不保存小数点。
if(exponent>0)
{
if(exponent>res.size()-1)
{
res.insert(res.size(),exponent-(res.size()-1),'0');
} else if(exponent1)
{
res.insert(1+exponent,1,'.');
}
} else if(exponent<0)
{
exponent=-exponent;
res.insert(0,exponent,'0');
res.insert(1,1,'.');
}
else
{
res.insert(1,1,'.');
}
if(!sign)
res='-'+res;
cout<return 0;
}
Reversing Linked List
思路:目前遇到的所有链表题都一个共性,每个结点地址和值是一一对应的,其它的可变,所以,完全可以用数组模拟,标准库reverse函数一上,秒杀。
//
// @author prime on 2017/7/2.
//
#include
#include
#include
using namespace std;
struct Node
{
int address;//5位
int val;
int next;
};
int main()
{
int start,N,K;
scanf("%d%d%d",&start,&N,&K);
vector in(100000),res;
for (int i=0,addr;iscanf("%d",&addr);
scanf("%d%d",&in[addr].val,&in[addr].next);
in[addr].address=addr;
}
for (int begin=start;begin!=-1;begin=in[begin].next)
res.push_back(in[begin]);
for (auto it=res.begin();itif(it+K<=res.end())
reverse(it,it+K);
for (int i=0;iif(i==res.size()-1)
{
printf("%05d %d -1",res[i].address,res[i].val);
break;
}
printf("%05d %d %05d\n",res[i].address,res[i].val,res[i+1].address);
}
return 0;
}
思路:还是老生常谈的排序,注意这个题几个点:未提交任何题目,或者提交的都没通过编译的不输出!否则就算0分也要输出。我这里用了个标志位valid,所以排序时要先按valid排序再根据id排,不然可能提前遇到了valid为false的,但是后面还有valid为true的呢!另外,第一个元素不用,排序的时候不要再排它了!!!
//
// @author prime on 2017/7/2.
//
#include
#include
using namespace std;
struct People
{
int id;
int score[6];//5道题得分情况
int total_score;
int perfect_num;//完美通过的题目数量;
int rank;//最后的排名
bool valid;
};
bool cmp(const People&o1,const People&o2)
{
if(o1.total_score!=o2.total_score)
return o1.total_score>o2.total_score;
else if(o1.perfect_num!=o2.perfect_num)
return o1.perfect_num>o2.perfect_num;
else if(o1.valid!=o2.valid)//必须加上这个,不然最后一个过不去
return o1.valid>o2.valid;
else
return o1.idint main()
{
int N,K,M;
scanf("%d%d%d",&N,&K,&M);
int p[10];//五道题的分值
for (int i=1;i<=K;++i)
scanf("%d",&p[i]);
vector in(N+1);
for (int i=1;i<=N;++i)
{
fill(in[i].score,in[i].score+6,-2);//一开始得分全部是-2
/*in[i].total_score=0;
in[i].valid=false;
in[i].perfect_num=0;*/
}
for (int i=0;iint id,problem_id,score;
scanf("%d%d%d",&id,&problem_id,&score);
if(in[id].score[problem_id]>=score)
continue;
else
{
in[id].id=id;
if(score>=0)
{//这次成绩有效
in[id].valid=true;//有一个得分为正表示有效
if(in[id].score[problem_id]>0)
in[id].total_score+=score-in[id].score[problem_id];
else
in[id].total_score+=score;
}
in[id].score[problem_id]=score;
if(score==p[problem_id])
{
in[id].perfect_num++;
}
}
}
sort(in.begin()+1,in.end(),cmp);
in[1].rank=1;
for (int i=2;iif(!in[i].valid)
break;
if(in[i].total_score==in[i-1].total_score)
in[i].rank=in[i-1].rank;
else
in[i].rank=i;
}
for (int k=1;kif(!in[k].valid)
break;
printf("%d %05d %d ",in[k].rank,in[k].id,in[k].total_score);
for (int i=1;i<=K;++i)
{
if(in[k].score[i]>=0)
printf("%d",in[k].score[i]);
else if(in[k].score[i]==-1)//-1表示没有通过编译
printf("0");
else//等于-2表示从来没提交过
printf("-");
if(i!=K)
printf(" ");
}
printf("\n");
}
return 0;
}
Forwards on Weibo
和1004的背景相似。
思路:一开始输入只给出了每个人关注的用户,只需要转换一下思路就可以变成每个人的follower。运用BFS对有向图进行广度优先遍历即可,注意需要判断深度。另外,一开始的起点深度为0,且起点发的文章不计入统计。
//
// @author prime on 2017/7/3.
//
#include
#include
#include
using namespace std;
int N,L;
vector <vector<int>> G;
bool visited[1005];
struct Node
{
int id;
int layer;//第几层
};
int BFS(int u)
{//返回总共转发的次数
fill(visited,visited+1005, false);
deque queue;
//头结点入队列
Node top;
top.id=u;
top.layer=0;
queue.push_back(top);
visited[u]=true;//visited保证每个元素只进一次队列
int res=0;
while(!queue.empty())
{
top=queue[0];
queue.pop_front();
for (int i=0;iif(!visited[G[top.id][i]]&&top.layer1;
queue.push_back(next);
visited[G[top.id][i]]=true;
res++;//不能再pop的时候统计,因为这样起点也算进来了,起点不算的。
}
}
}
return res;
}
int main()
{
scanf("%d%d",&N,&L);
G.resize(N+1);
for (int i=1;i<=N;++i)
{
int k;
scanf("%d",&k);
for (int j=0;jint id;
scanf("%d",&id);
G[id].push_back(i);
/*注意不是G[i].push_back(id),只有这样得到的G[id]才是每个id的follower*/
}
}
int K;
scanf("%d",&K);
for (int i=0;iint query;
scanf("%d",&query);
printf("%d\n",BFS(query));
}
return 0;
}
Kuchiguse
思路:后缀比对起来比较麻烦,在输入一个字符串后顺便反转它就好了。然后比对前缀,一开始res等于s[0],然后比对s[1]到s[N],不相等就截取一段。最后看res是否是空串,不是就倒序输出。
一开始直接用后缀比较了,结果最后一个用例过不去,,不知道为什么。。
//
// @author prime on 2017/7/3.
//
#include
#include
#include
using namespace std;
int main()
{
int N;
cin>>N;
getchar();//吃掉换行符
string s[N];
for (int i=0;icin,s[i]);
reverse(s[i].begin(),s[i].end());
}
string res=s[0];
for (int i=1;iint end=min((int)res.size(),(int)s[i].size());
for (int k=0;kif(res[k]!=s[i][k])
{
res=res.substr(0,k);
break;
}
}
}
if(res.size()==0)
cout<<"nai";
else
{
for (auto it=res.rbegin();it!=res.rend();it++)
cout<<*it;
}
return 0;
}
Hashing
思路:如果知道Quadratic probing是二次探测就没问题了,此处只要求递增的二次探测。
记住,这种题没必要真的插入数字,只有记录有没有即可,所以果断用bool
//
// @author prime on 2017/7/3.
//
#include
#include
#include
using namespace std;
bool isprime(int M)
{
if(M<=1)
return false;
for(int i=2;i<=sqrt(M);i++)
{
if(M%i==0)
return false;
}
return true;
}
int main()
{
int M,N;
scanf("%d%d",&M,&N);
while(!isprime(M))
{
M++;
}
vector<bool > a(M, false);
for (int i=0;iint num,pos;
scanf("%d",&num);
pos=num%M;
if(!a[pos])
{
printf("%d",pos);
a[pos]=true;
}
else
{
bool flag=false;
for (int step=1;stepif(!a[pos])
{
flag=true;
printf("%d",pos);
a[pos]=true;
break;
}
}
if(!flag)
printf("-");
}
if(i!=N-1)
printf(" ");
}
return 0;
}
Total Sales of Supply Chain
思路:经典题目,树的DFS遍历。用product数组保存零售商的货品数量。
//
// @author prime on 2017/7/4.
//
#include
#include
using namespace std;
double total_sale=0;
double R;
vector<int> tree[100000];
int product[100000];//记录零售商i的商品数量
void DFS(int u, double price)
{
if(tree[u].size()==0)
{
total_sale+=product[u]*price;
}
else
{
for (int i=0;i1+R)*price);
}
}
int main()
{
int N;
double P;
scanf("%d %lf %lf",&N,&P,&R);
R/=100;
for (int i=0;iint num;
scanf("%d",&num);
if(num==0)
{
scanf("%d",&product[i]);
continue;
}
for (int j=0;jint id;
scanf("%d",&id);
tree[i].push_back(id);
}
}
DFS(0,P);
printf("%.1lf",total_sale);
return 0;
}
Graduate Admission
思路:还是经典的排序,我一开始的思路是用rank和target记录上一个人的排名和选的学校,然后看下一个人是不是一样,一样就录取(用于学校名额满的情况),但是这种有问题,虽然ac了,但是确实不符合题意,比如如下用例
3 2 1
1 1
100 100 0
100 100 1
100 100 0
按理说,0号和2号都应该进入学校0才对,但是如果用这样2号就会进不去!
所以,更健全的思路是用一个结构体保存一个一个学校的最后一名,这样就没问题了。所以,这种可能会”交叉”的情况,还是应该仔细考虑是用一个变量保存还是用一组变量保存。
#include
#include
#include
using namespace std;
struct Student
{
int id;
int Ge,Gi;
int choice[5];
int rank;
int total;
};
struct School
{
int last_rank;//招收的最后一个的学生的排名
int num;//收多少人
vector<int> receive;
};
bool cmp(const Student& o1,const Student&o2)
{
if(o1.total!=o2.total)
return o1.total>o2.total;
else if(o1.Ge!=o2.Ge)
return o1.Ge>o2.Ge;
else return o1.idint main()
{
int N,M,K;
scanf("%d%d%d",&N,&M,&K);
vector sch(M);
vector stu(N);
for (int i=0;iscanf("%d",&sch[i].num);
}
for (int i=0;iscanf("%d%d",&stu[i].Ge,&stu[i].Gi);
for (int j=0;jscanf("%d",&stu[i].choice[j]);
stu[i].total=(stu[i].Ge+stu[i].Gi)/2;
stu[i].id=i;
}
sort(stu.begin(),stu.end(),cmp);
stu[0].rank=1;
for (int i=1;iif(stu[i].total==stu[i-1].total&&stu[i].Ge==stu[i-1].Ge)
{
stu[i].rank=stu[i-1].rank;
}
else
{
stu[i].rank=i+1;
}
}
for (int i=0;iint prefer;
for (int j=0;jif(sch[prefer].num>0)
{
sch[prefer].num--;
sch[prefer].receive.push_back(stu[i].id);
sch[prefer].last_rank=stu[i].rank;
break;
}
else if(sch[prefer].last_rank==stu[i].rank)
{
sch[prefer].receive.push_back(stu[i].id);
break;
}
}
}
for (int i=0;iif(sch[i].receive.size()==0)
printf("\n");
else
{
sort(sch[i].receive.begin(),sch[i].receive.end());
for (int j=0;jprintf("%d",sch[i].receive[j]);
if(j!=sch[i].receive.size()-1)
printf(" ");
}
printf("\n");
}
}
return 0;
}
最后把虽然ac但是不对的代码也附上吧
//
// @author prime on 2017/7/4.
//
#include
#include
#include
using namespace std;
struct Student
{
int id;
int Ge,Gi;
int choice[5];
int rank;
int total;
};
bool cmp(const Student& o1,const Student&o2)
{
if(o1.total!=o2.total)
return o1.total>o2.total;
else
return o1.Ge>o2.Ge;//把这个换成下面注释掉的也一样!!!
/*else if(o1.Ge!=o2.Ge)
return o1.Ge>o2.Ge;
else return o1.id
} /*如果一个元素既不大于又不小于另一个元素,它们就相等*/
int main()
{
int N,M,K;
scanf("%d%d%d",&N,&M,&K);
vector<int> quota(M);//各个学校名额
vector<int> res[M];
vector stu(N);
for (int i=0;iscanf ("%d","a[i]);
for (int i=0;iscanf("%d%d",&stu[i].Ge,&stu[i].Gi);
for (int j=0;jscanf("%d",&stu[i].choice[j]);
stu[i].total=(stu[i].Ge+stu[i].Gi)/2;
stu[i].id=i;
}
sort(stu.begin(),stu.end(),cmp);
stu[0].rank=1;
for (int i=1;iif(stu[i].total==stu[i-1].total&&stu[i].Ge==stu[i-1].Ge)
{
stu[i].rank=stu[i-1].rank;
}
else
{
stu[i].rank=i+1;
}
}
int rank=-1,target=-1;//记录上一个人的排名和他选的学校
for (int i=0;ifor (int j=0;jint prefer=stu[i].choice[j];
if(quota[prefer]>0)
{
rank=stu[i].rank;
target=prefer;
quota[prefer]--;
res[prefer].push_back(stu[i].id);
break;
}
else if(stu[i].rank==rank&&prefer==target)
{
res[prefer].push_back(stu[i].id);
break;
}
}
}
for (int i=0;iif(res[i].size()==0)
printf("\n");
else
{
sort(res[i].begin(),res[i].end());
for (int j=0;jprintf("%d",res[i][j]);
if(j!=res[i].size()-1)
printf(" ");
}
printf("\n");
}
}
return 0;
}