第一题:就是把字符串按照它要求的输出。
#include <iostream> #include<cstdio> #include<cstring> using namespace std; char op[100]; char out[100][100]; int main() { while(~scanf("%s",op)) { int len=strlen(op); int a=(len+2)/3; int b=(len+2)-2*a; int fr=0,ed=len-1; for(int i=1;i<a;i++) { for(int j=1;j<=b;j++) { if(j==1) out[i][j]=op[fr++]; else if(j==b) out[i][j]=op[ed--]; else out[i][j]=' '; } } for(int j=1;j<=b;j++) out[a][j] = op[fr++]; for(int i=1;i<=a;i++) { for(int j=1;j<=b;j++) { printf("%c",out[i][j]); } printf("\n"); } } return 0; }
第二题:有多个单词,现在给你两个单词的首地址,和很多字母的节点。
一开始以为只有2个单词,所以有测试数据过不去。
其实只要把所有单词拼接起来成一个静态链表,然后再从给的两个首地址
遍历一次找到共同点就行了。
这里实现上学到了些东西:
1. 就是%d 会忽略前导 0 。
2. 可以用 %05d 来控制输出。 0会在前面补上0。
参考代码:
#include<stdio.h> #include<stdlib.h> #include<string.h> struct Node{ int next; char ch; }; Node node[100005]; int vis[100005]; int main(){ int start1,start2,N,a,b; char c; scanf("%d%d%d",&start1,&start2,&N); memset(vis,0,sizeof(vis)); for(int i=0;i<N;i++){ scanf("%d %c %d",&a,&c,&b); node[a].ch=c; node[a].next=b; } while(start1!=-1){ vis[start1]=1; start1=node[start1].next; } bool flag=false; int ans; while(start2!=-1){ if(vis[start2]==1){ flag=true; ans=start2; break; } start2=node[start2].next; } if(flag) printf("%05d\n",ans); else printf("-1\n"); //system("pause"); return 0; }
第三题:
一开始用 DP 做,WA。。
其实就是一贪心题,想清楚情况就行了。
参考下面一人的,已经很详细了。。
http://www.cnblogs.com/XBWer/p/3866486.html
#include<stdio.h> #include<algorithm> #include<iostream> using namespace std; typedef struct { double pos; double price; }gasstation; gasstation gasst[502]; bool cmp(gasstation a,gasstation b) { if(a.pos<b.pos) return true; return false; } int main() { double Cmax,D,Davg; int N; scanf("%lf%lf%lf%d",&Cmax,&D,&Davg,&N); int i; for(i=0;i<N;i++) scanf("%lf%lf",&gasst[i].price,&gasst[i].pos); sort(gasst,gasst+N,cmp); if(D==0) { printf("0.00\n"); return 0; } if(gasst[0].pos!=0) { printf("The maximum travel distance = 0.00\n"); return 0; } int curstnum=0; //当前所处的油站编号,即当前的位置 double curgas=0; //当前的油量 double curcost=0; //当前的花费 bool flag=false; //是否达到目的 double maxrundis=Cmax*Davg; //邮箱加满最远能行驶的距离 while(!flag) { bool tag=false; //最大距离内是否有加油站 bool ifcheaper=false; //是否有便宜的 double cheapestprice=10000; //找出最便宜的 int cheapestnum; //没有更便宜的情况下,找出最便宜的 for(i=curstnum+1;i<N;i++) { if((gasst[i].pos-gasst[curstnum].pos)<=maxrundis) //范围内 { tag=true; //有加油站 if(gasst[i].price<gasst[curstnum].price) //情况3-a { //且有更便宜的 ifcheaper=true; double dist=gasst[i].pos-gasst[curstnum].pos; double needgas=dist/Davg-curgas; curgas=0; curcost+=(needgas*gasst[curstnum].price); curstnum=i; break; } if(gasst[i].price<cheapestprice) { cheapestprice=gasst[i].price; cheapestnum=i; } } else break; } if(!ifcheaper&&(maxrundis>=(D-gasst[curstnum].pos))) //说明已经可以到达目的地了,情况1 { double dist=D-gasst[curstnum].pos; double needgas=dist/Davg-curgas; curcost+=needgas*gasst[curstnum].price; printf("%.2lf\n",curcost); return 0; } if(tag&&!ifcheaper) //情况3-b { double needgas=Cmax-curgas; curcost+=(needgas*gasst[curstnum].price); double dist=gasst[cheapestnum].pos-gasst[curstnum].pos; curgas=Cmax-dist/Davg; curstnum=cheapestnum; } else if(!tag) //情况2 { printf("The maximum travel distance = %.2lf\n",gasst[curstnum].pos+maxrundis); return 0; } } return 0; }
第四题:
题意: 找出一个团伙的首领,现在如果 AAA 与 BBB 打电话,则AAA 与 BBB 属于同一个团伙。
并且每个人都有一个权值 为他与其他人通话时间的总长度。每个团伙的总权值为每对人通话时间的总长度。
现在你要输出的团伙要满足一下条件:
1. 团伙人数大于2个人
2. 团伙的总通话时间大于给的 k
分析:
就是一个并查集,一开始我没考虑到 团伙 合并的情况,总有一组测试数据错误。
我们来看一个数据
AAA BBB 30
我们需要把 AAA自身权值 和 它的 团伙(祖先)权值 + 30
同理BBB 也一样。
并且一定要注意维护下团伙的头领 。因为AAA BBB 的权值改变了,就有可能成为头领。
然后 BBB 的团伙 合并到 AAA的团伙里去。
需要更新这个新团伙的
1. 总通话时间。
2. 总人数。
3. 头领。
思路出来了,具体实现就可以用到
map容器来映射。
#include<iostream> #include<cstdio> #include<algorithm> #include<string> #include<map> #include<vector> using namespace std; #define MAXN 2000 struct node { int num,sum,self; string head; string fa; bool operator<(const node&a)const { return head<a.head; //字典序输出 } }ans[MAXN]; string v[MAXN]; map<string,int> vis; map<string,node> gang; int coun; void init_node(string a) { gang[a].sum=0; gang[a].num=1; gang[a].head=a; gang[a].self=0; gang[a].fa=a; } string find(string a,int key) { if(gang[a].fa!=a) return gang[a].fa=find(gang[a].fa,key); else { gang[a].sum+=key; return gang[a].fa; } } void merge(string a,string b) { string fa=gang[a].fa; string fb=gang[b].fa; if(gang[gang[fa].head].self < gang[a].self) gang[fa].head=a; if(gang[gang[fb].head].self < gang[b].self) //先维护一下各自的头领。 gang[fb].head=b; if(fa==fb) return; //如果是同一团伙 , 就不要合并了。 gang[fb].fa=fa; gang[fa].sum+=gang[fb].sum; gang[fa].num+=gang[fb].num; int t1=gang[gang[fa].head].self; int t2=gang[gang[fb].head].self; gang[fa].head=t1>t2?gang[fa].head : gang[fb].head; } void init() { coun=0; vis.clear(); gang.clear(); } int main() { int n,k; while(~scanf("%d%d",&n,&k)) { string a,b; int c; init(); for(int i=1;i<=n;i++) { cin>>a>>b>>c; if(gang[a].num==0) init_node(a); if(gang[b].num==0) init_node(b); gang[a].self+=c; gang[b].self+=c; find(a,c); find(b,0); merge(a,b); v[coun++]=a; v[coun++]=b; } int num=0; for(int i=0;i<coun;i++) { string fa=find(v[i],0); if(vis[fa]) continue; if(gang[fa].num>2&&gang[fa].sum>k) { ans[num].head=gang[fa].head; ans[num++].num=gang[fa].num; } vis[fa]=1; } if(num==0) printf("0\n"); else { cout<<num<<endl; sort(ans,ans+num); for(int i=0;i<num;i++) { cout<<ans[i].head<<" "<<ans[i].num<<endl; } } } return 0; }