现在的位置: 首页 > 综合 > 正文

2012浙大

2019年08月21日 ⁄ 综合 ⁄ 共 4797字 ⁄ 字号 评论关闭

第一题:就是把字符串按照它要求的输出。

#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;
}

【上篇】
【下篇】

抱歉!评论已关闭.