河南省第十届大学生程序设计竞赛 A,B,C,D,F,G,H 题解

H: Intelligent Parking Building

时间限制: 1 Sec  内存限制: 128 MB
提交: 22  解决: 20
[提交][状态][讨论版]

题目描述

There is a new revolution in the parking lot business: the parking  building. The concept is simple: you drive your car into the elevator at the entrance of the building, and the elevator and conveyor belts drag the car to an empty parking spot, where the car remains until you pick it up. When you return, the elevator and conveyor belts move your car back to the entrance and you’re done.
The layout of the building is simple. There is one central elevator that transports the cars between the different floors. On each floor there is one giant circular conveyor belt on which the cars stand. This belt can move in clockwise and counterclockwise direction. When the elevator arrives on a floor, it becomes part of the belt so that cars can move through it.
At the end of the day the building is usually packed with cars and a lot of people come to pick them up. Customers are processed in a first come first serve order: the elevator is moved to the floor of the first car, the conveyor belt moves the car on the elevator, the elevator is moved down again, and so on. We like to know how long it takes before the last customer gets his car. Moving the elevator one floor up- or downwards takes 10 seconds and moving  the conveyor belt one position in either direction takes 5 seconds. 

输入

On the first line one positive number: the number of testcases, at most 30.  Each test case specifies:
•One line with two integers h and l with 1 ≤ h ≤ 50 and 2 ≤ l ≤ 50: the height of the parking tower and the length of the conveyor belts.
•h lines with l integers: the initial placement of the cars. The jth number on the ith line describes the jth position on the ith floor. This number is −1 if the position is empty, and r if the position is occupied by the rth car to pick up. The positive numbers form a consecutive sequence from 1 to the number of cars. The entrance is on the first floor and the elevator (which is initially empty) is in the first position. There is at least one car in the parking tower.

输出

For each test case generate a single line containing a single integer  that is the number of seconds before the last customer is served.

样例输入

3

1 5

1 -1 -1 -1 2
1 5
2 -
1 -1 -1 1
3 6
-1 
5 6 -1 -1 3

-1 -1 7 -1 2 9
-1 10 4 1 8 -1

样例输出

5

10

320

模拟:
电梯 上下来回一层20s  传送带左右 移动一个位置 5s
记录 上一次电梯位置:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<cmath>
#include<set>
using namespace std;
const int N=260;
 
struct Fuck{
    int x,y;
}a[N];
 
int b[56];//每层电梯所对车位的编号
 
int main()
{
    int n,h,l,maxx;
    while(cin>>n)
    {
        while(n--)
        {
            memset(b,0,sizeof(b));//初始车位编号是0的与电梯相邻
            scanf("%d%d",&h,&l);
            maxx=0;
            for(int i=0;i<h;i++)
                for(int j=0;j<l;j++)
                {
                    int m;
                    cin>>m;
                    if(m!=-1)
                    {
                        a[m].x=i;
                        a[m].y=j;
                        maxx=max(maxx,m);
                    }
                }
            int ant=0;
            for(int i=1;i<=maxx;i++)//模拟一个一个出
            {
                int cen=a[i].x;//i的所在的层数
                int num=a[i].y;//所在的编号
                ant+=2*cen*10;
               // cout<<ant<<endl;
                ant+=5*min(abs(num-b[cen]),l-abs(num-b[cen]));//逆时针  顺时针
                //cout<<abs(num-b[i])<<" "<<l-abs(num-b[i])<<endl;
                b[cen]=num;
                //cout<<"B"<<b[i]<<endl;
            }
            cout<<ant<<endl;
        }
    }
    return 0;
}

问题 B: 情报传递

时间限制: 2 Sec  内存限制: 128 MB
提交: 35  解决: 17
[提交][状态][讨论版]

题目描述

抗日战争时期,在国共合作的大背景下,中共不断发展壮大,其情报工作也开始由获取警报性、保卫性信息,向获取军政战略性情报转变。各系统情报组织遵循"荫蔽精干,长期埋伏,积蓄力量,以待时机"的隐蔽战线工作方针,开展了卓有成效的情报工作。
***特科组是中共情报工作的一个杰出范例,它以点为主、系统延伸、分散辐射的力量格局,异地领导、分头派遣、单线联系的组织形式。以打入、拉出、统战联络、内线为主的工作方式,形成了一个传递信息隐蔽、效用及时、形式多样的情报网络。
***特科组的情报人员共有N人,其代号分别为0,1,……,N-1。 0号是最高领导人,特工之间有一套严格的单线联络程序,即,每个特工人员只有一个上线,他获得的情报需层层上传递到0号手里,由0号发报出去。
特工i在传递情报时,若通往到0号的通道尚未建立,则需要建立一级级单线通道;若他的上线已建立好通道,只需建立两人通道,信息发送给上线;依次类推。若特工i已建立好到0号的通道,则直接发出情报。日伪统治中心南京,既是情报来源丰富的地方,又是特工人员活动最危险的地方。因此,一旦某个特工处于不安全状态,他必须马上撤离,同时他的所有下线(处在通道上的一级级下线)也一同撤离。
已知***特科组的组织结构,你的任务是计算,当某特工i需要发送情报时,最少需要建立几个情报人员的通道;当某特工i处于不安全状态时,最少需要撤离多少人员。

输入

第一行一个整数:  N           ( 1≤N ≤5060 )
接下来一行有N-1 个整数,  A1 A2 ……An-1  ,其中Ai是编号i的上线。
下一行一个整数:  M         表示有M个状态,( 1≤M ≤5060 )
接下来有M行 :有两种形式:  Send i    特工i处于要发送情报状态;
                             Danger i  特工i处于不安全状态

输出

输出占M行 ,对于Send i,输出最少需要建立通道的情报人员数,若特工i处于通道线上,输出0;对于Danger i,输出最少需要撤离多少人员,若特工i不处于通道线上,则输出0.

样例输入

10

0 1 2 1 3 0 0 3 2

10
Send 0

Send 3

Danger 2

Send 7
Send 5
Send 9

Danger 9

Send 4

Send 1

Send 9

样例输出

1
3
2

1

3

1

1

1

0

1

提示

情况可分为 类似于一个 树, 每个人有上级和下级,   传递 找上级看是否 未标记,未标记+1 , 向下查询,如果标记则+1

注意要点:
1 :   0 也需要传递
2:  当前情况与上一次有关

向上简单 数组存上级 查询上去;
向下 可以用dfs 或者bfs
我这里用的是 链表 vector+ queue 队列  链表存 每个数的下级;  用队列 来进行 查询 循环

代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)

using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};

int vis[maxn];
int boss[maxn];
vector<int> lis[6000];
void find_up(int x)
{
    int ans=0;
    while(!vis[x])
    {
        ans++;
        vis[x]=1;
        x=boss[x];
    }
    cout<<ans<<endl;
}

void find_down(int x)
{
    queue<int> Q;

    int ans=0;
    Q.push(x);
    if(vis[x])
    {
        //ans++;
        vis[x]=0;
        while(!Q.empty())
        {
            int t=Q.front();
            Q.pop();
            ans++;
            for(int i=0;i<lis[t].size();i++)
            {
                if(vis[lis[t][i]]==1)
                {
                    //ans++;
                    vis[lis[t][i]]=0;
                    Q.push(lis[t][i]);
                }
            }
        }
    }


    cout<<ans<<endl;

}
int main()
{
    int n;
    //FIN;
    while(~S1(n))
    {
        mem(vis,0);
        mem(lis,0);
        int x;
        for(int i=1;i<n;i++)
        {

            S1(x);
            boss[i]=x;//上
            lis[x].push_back(i);//下
        }
        int m;
        S1(m);
        char str[10];
        while(m--)
        {
            scanf("%s %d",str,&x);
            if(str[0]=='S')
                find_up(x);
            else
                find_down(x);
        }
    }
    return 0;
}


123

问题 A: 谍报分析

时间限制: 1 Sec  内存限制: 128 MB
提交: 19  解决: 18
[提交][状态][讨论版]

题目描述

“八一三”淞沪抗战爆发后,***几次准备去上海前线视察和指挥作战。但都因为宁沪之间的铁路和公路遭到了敌军的严密封锁,狂轰滥炸,一直未能成行。 
***特科组织,其主要任务是保卫***的安全,了解和掌握敌方的动向。经过一段时间的监听,谍报组获取了敌方若干份密报,经过分析,发现密文中频繁出现一些单词,情报人员试图从单词出现的次数中,推出敌军的行动计划。
请你编程,快速统计出频率高的前十个单词。

输入

密文是由英语单词(小写字母)组成,有若干段。单词之间由一个或多个空格分开,自然段之后可以用一个“,”或“。”表示结束。整个内容的单词数量不超过10000,不同的单词个数不超过500.

输出

输出占10行,每行一个单词及出现的次数,中间一个空格。要求按频率降序输出,出现次数相同的单词,按字典序输出。

样例输入

shooting is at shanghai station. shooting  must  

be carried out. shooting  shooting.

shanghai station must be surrounded,  at least a team of  one hundred  soldiers to fight.  twenty  five soldiers shooting in the north, twenty  five soldiers shooting in the south,  twenty  five soldiers  shooting in  the east, twenty  five soldiers shooting in the west.

样例输出

shooting 8

soldiers 5

five 4
in 4

the 4

twenty 4

at 2

be 2

must 2

shanghai 2

提示


水题:

#include<iostream>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<stdio.h>
using namespace std;
struct Fuck{
    string str;
    int num;
}c[10004];
 
int cmp(Fuck a,Fuck b)
{
    if(a.num==b.num)
        return a.str<b.str;
    return a.num>b.num;
}
using namespace std;
int main()
{
    string str,str1;
    map<string,int>mymap;
    mymap.clear();
    int l=0;
    while(cin>>str)
    {
        int len=str.length();
        if(str[len-1]=='.'||str[len-1]==',')
            str1=str.substr(0,len-1);
        else
            str1=str;
        l++;
        mymap[str1]++;
    }
    map<string,int>::iterator it;
    int i=0;
    for(it=mymap.begin();it!=mymap.end();it++)
    {
        c[i].str=it->first;
        c[i].num=it->second;
        i++;
    }
    int len=i;
    sort(c,c+len,cmp);
    for(int i=0;i<10;i++)
        cout<<c[i].str<<" "<<c[i].num<<endl;
    return 0;
}

问题 C: 最小密钥

时间限制: 1 Sec  内存限制: 128 MB
提交: 26  解决: 22
[提交][状态][讨论版]

题目描述

在中国近代史上,暂编***军绝对是一支能打硬仗,大名鼎鼎的行动部队。“一二八”上海抗战,暂编***军就曾打得小日本四易主帅。
*月**号,暂编***军计划组成一个行动大队,派出N名队员潜伏在***地,发动一次大规模的巷战行动。每名队员有自己的代号Ai,为了更好的配合作战,他们需要获得一个密钥Key,  然后各自迅速移动到Ai  MOD  Key位置,**时刻一起开战。
作战方案已经定好,你能帮***行动大队快速找个满足条件的最小密钥Key吗?
MOD表示取模运算,要求不能有多名队员待在同一个位置。

输入

第一行:T表示以下有T组测试数据(1≤T≤5)
对每组数据,
第一行:N表示行动人员数(1<=N<=3000)
接下来一行有N个整数,分别表示每个队员的代号Ai(1<=Ai<=20000)

输出

对每组测试数据,输出占一行,一个整数 Key.

样例输入

2
3
1 2 3

5

4 6 9 10 13

样例输出

3

8

#include<iostream>
#include<cstdio>
#include<cstring>
 
using namespace std;
 
int main()
{
    int n,a[3005],T,vis[20005];
    scanf("%d",&T);
    while(T--){
        memset(vis,0,sizeof(vis));
        int flag,mixx=-1;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            if(a[i]>mixx)
                mixx=a[i];
        }
        for(int i=n;i<=mixx;i++){
            memset(vis,0,sizeof(vis));
            flag=0;
            for(int j=0;j<n;j++){
                if(vis[a[j]%i]==0){
                    vis[a[j]%i]=1;
                }
                else{
                    flag=1;
                    break;
                }
            }
            if(!flag){
                printf("%d\n",i);
                break;
            }
        }
         
    }
    return 0;
}


年终奖金

时间限制: 2 Sec  内存限制: 128 MB
提交: 37  解决: 23
[提交][状态][讨论版]

题目描述

***公司承接了N个项目需要年底完成,每个项目有一定的难度系数。由于项目太多了,需要招聘大量的技术人员。要求每个技术人员至少完成K个项目。
考虑到有些项目之间相似性以及项目的难易程度,为了避免某些员工只挑选轻松项目,CEO提出了一个奖励机制,当技术人员完成分配给他的任务后,年终可以得到一笔奖金,其得到的酬金将是C + (Tmax–Tmin)2。其中,Tmax表示所做项目的最大的难度系数,Tmin是难度系数的最小值。
你能否计算一下,为了完成所有项目,***公司年终至少需要支付多少酬金?

输入

输入有多组测试数据。对每组测试数据:
第一行:NKC(1<=N,K<=1001<=C<=5000)
第二行N个正整数分别描述N个项目的难度系数。(1<=难度系数<=10000)

输出

对每组测试数据:输出占一行,一个整数。即,***公司年终至少需要支付的酬金数。

样例输入

2 1 1

2 4

10 2 3

1 4 10 3 10 1 8 3 8 3

样例输出

2

13

提示

第一组测试数据,如果一个人完成,酬金为1 + (4–2)2 = 5;如果分给两个人去完成,收费为1 + 1 = 2。

DP

最少k 个任务, 排下序,  然后 从k- n  判断  是否要让他来做 这个任务, 或者  全部工作让一个人来做;

dp 存的是时间

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)

using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};

ll inv[maxn*2],fac[maxn];
ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;}
void INV(){inv[1] = 1;for(int i = 2; i < maxn; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){ x=1; y=0; d=a; }else{ ex_gcd(b,a%b,d,y,x); y-=x*(a/b);}}
void Fac(){fac[0]=1;for(int i=1;i<=maxn;i++)fac[i]=(fac[i-1]*i)%MOD;}
ll inv_exgcd(ll a,ll n){ll d,x,y;ex_gcd(a,n,d,x,y);return d==1?(x+n)%n:-1;}
ll inv1(ll b){return b==1?1:(MOD-MOD/b)*inv1(MOD%b)%MOD;}
ll inv2(ll b){return qpow(b,MOD-2);}
ll cal(ll m,ll n){if(m<n)return 0;return (fac[m]*inv[fac[n]]%MOD)%MOD*inv[fac[m-n]]%MOD;}
ll cals(ll m,ll n){if(m<n)return 0;return (fac[m]*inv1(fac[n])%MOD)%MOD*inv1(fac[m-n])%MOD;}

int dp[maxn],a[maxn];
int main()
{
	int n,k,c;
	while(~scanf("%d %d %d",&n,&k,&c))
	{
		mem(a,0);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		for(int i=1;i<=maxn;i++)
			dp[i]=INF;
		dp[0]=0;
		sort(a+1,a+n+1);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=i-k+1;j++)
			{
				if(j>=k||j==1)
					dp[i]=min((a[i]-a[j])*(a[i]-a[j])+c+dp[j-1],dp[i]);
			}
			
		cout<<dp[n]<<endl;
	}
	return 0;
}


123

问题 F: Binary to Prime

时间限制: 1 Sec  内存限制: 128 MB
提交: 30  解决: 22
[提交][状态][讨论版]

题目描述

To facilitate the analysis of  a DNA sequence,  a DNA sequence is represented by a binary  number. The group of  DNA-1 has discovered a great new way .  There is a certain correlation between binary number and prime number. Instead of using the ordinary decadic numbers, they use prime base numbers. Numbers in this base are expressed as sequences of zeros and ones similarly to the binary numbers, but the weights of bits  in the representation are not powers of two, but the elements of the primes  ( 2, 3, 5, 7,... ). 

For example  01101 , ie. 2+5+7=14 

Herefore, it is necessary to convert the binary number to the sum of prime numbers

输入

The input consists of several instances, each of them consisting of a single line. Each line of the input contains a 01 string, length of not more than 150.  The end of input is not marked in any special way.

输出

For each test case generate a single line containing a single integer , The sum of the primes.

样例输入

000010

0011

11001

样例输出

3

5

20

#include<iostream>
#include<cstdio>
#include<cstring>
 
using namespace std;
 
int main()
{
    int a[1005]={0},c[200];
    for(int i=2;i<1000;i++){
        for(int j=i+i;j<1000;j+=i){
            a[j]=1;
        }
    }
    int k=0;
    for(int i=2;i<1000;i++){
        if(a[i]==0){
            c[k++]=i;
        }
    }
    char b[200];
    while(cin>>b){
        int sum=0;
        int i;
        int n=strlen(b);
        for(int j=n-1;j>=0;j--)
            if(b[j]=='1'){
                sum+=c[n-j-1];
            }
        printf("%d\n",sum);
    }
    return 0;
}

 Plumbing the depth of lake

时间限制: 1 Sec  内存限制: 128 MB
提交: 22  解决: 15
[提交][状态][讨论版]

题目描述

There is a mysterious lake in the north of Tibet. As the sun shines, the surface of the lake is colorful and colorful. The lake was unfathomable in rainy weather.  After the probe,  It has an interesting bottom in that it is full of little hills and valleys. . Scientists wonders how deep the bottom of the lake is.

Scientists use the most advanced radar equipment to detect the bottom of the lake. It is the discovery that the deepest part is relatively flat. Thet want to know the largest depth number only if it is verified by the fact that the same depth appears in an adjacent reading.

To facilitate computing, scientists have put the lake as M * N grids . The depth  reading of each grid is already known. some readings might be 0-- It's a small island on the lake.
 
Find the greatest depth that appears in at least two 'adjacent'readings (where 'adjacent' means in any of the potentially eight squares that border a square on each of its sides and its diagonals). The lake has at least one pair of positive, adjacent readings.

输入

The first line of the input contains one integers T, which is the nember of  test cases (1<=T<=5).  Each test case specifies:

* Line 1: Two space-separated integers: M and N   (1 ≤ M,  N ≤ 50)
* Lines 2..M+1: Line i+1 contains N space-separated integers that  represent the depth of the lake across row i: Dij    (0 <= Dij <=1,000,000);

输出

For each test case generate a single line:  a single integer that is the depth of the lake determined.

样例输入

1
4 3
0 1 0

1 2 0

1 5 1
2 3 4

样例输出

1

#include<iostream>
#include<cstdio>
#include<cstring>
 
using namespace std;
int tx[8]={1,-1,0,0,1,1,-1,-1};
int ty[8]={0,0,1,-1,1,-1,1,-1};
 
int main()
{
    int m,n,a[55][55],maxx,T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&m,&n);
        maxx=-1;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&a[i][j]);
            }
        }
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                for(int k=0;k<8;k++){
                    int xx=i+tx[k];
                    int yy=j+ty[k];
                    if(a[i][j]==a[xx][yy]){
                        if(a[i][j]>maxx){
                            maxx=a[i][j];
                        }
                        break;
                    }
                }
            }
        }
        printf("%d\n",maxx);
    }
    return 0;
}


123



posted @ 2017-09-01 17:29  Sizaif  阅读(226)  评论(0编辑  收藏  举报