2012浙大

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

#include 
#include
#include
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



第二题:有多个单词,现在给你两个单词的首地址,和很多字母的节点。

一开始以为只有2个单词,所以有测试数据过不去。

其实只要把所有单词拼接起来成一个静态链表,然后再从给的两个首地址

遍历一次找到共同点就行了。


这里实现上学到了些东西:

1. 就是%d 会忽略前导 0 。

2. 可以用 %05d 来控制输出。 0会在前面补上0。


参考代码:

#include
#include
#include

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


第三题:

一开始用 DP 做,WA。。

其实就是一贪心题,想清楚情况就行了。

参考下面一人的,已经很详细了。。

http://www.cnblogs.com/XBWer/p/3866486.html

#include
#include
#include
using namespace std;

typedef struct
{
    double pos;
    double price;
}gasstation;
gasstation gasst[502];

bool cmp(gasstation a,gasstation b)
{
    if(a.pos=(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
#include
#include
#include
#include
#include
using namespace std;
#define MAXN 2000
struct node
{
    int num,sum,self;
    string head;
    string fa;
    bool operator<(const node&a)const
    {
        return head vis;
map 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;i2&&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<




你可能感兴趣的:(考研上机试题)