几个基础题

2016-08-04

题源:http://acm.timus.ru/problemset.aspx?space=1&page=8  

 

ctrl+f   搜索   Ural Regional School Programming Contest 2010

1.输入数字,输出对应区间的单词,如下图

输入的数字 输出
from 1 to 4 few
from 5 to 9 several
from 10 to 19 pack
from 20 to 49 lots
from 50 to 99 horde
from 100 to 249 throng
from 250 to 499 swarm
from 500 to 999 zounds
from 1000 legion

越是水的题,姿势越重要!!看姿势!!

代码:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int a[]={1,5,10,20,50,100,250,500,1000,2001};
char b[][8]={"few","several","pack","lots","horde","throng","swarm","zounds","legion"};
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<9;i++)
    {
        if(n>=a[i]&&n<a[i+1])
            puts(b[i]);
    }

    return 0;
}
View Code
2. 1786. Sandro's Biography

题目大意:给你一个字符串T,改其中的字符,使其中包含字符串S "Sandro";大写改成大写,小写改小写要花5毛钱,大小写互换再花5毛钱,问最少需要花多少钱可以成功?

思路:暴力吧~~~T和S头对齐,S串每次向右移动一位,计算需要花的钱,并用一个数sum记录,并更新最小值ans;最后输出ans即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

char a[]="Sandro";
char b[201];

bool type(char b)    //判断是否是小写
{
    return b>='a'&&b<='z';
}

int value(char aa)    //如果某个字符与'a'或'A'的差值,  是否可以大小写互换
{
    if(aa>='a') return aa-'a';
    return aa-'A';
}
int get(char aa,char bb) 
{
    if(aa==bb) return 0;
    if(type(aa)==type(bb)) return 5;
    if(value(aa)==value(bb)) return 5;   //只需大小写互换
    return 10;
}

int main()
{

    while(~scanf("%s",b))
    {
        int ans=0x3f3f3f3f;
        int lb=strlen(b);
        for(int i=0;i+5<lb;i++)
        {
            int sum=0;
            for(int j=0;j<6;j++)
                sum+=get(b[i+j],a[j]);    //注意这个i+j,不是i
            ans=min(ans,sum);
        }
        cout<<ans<<endl;
    }

    return 0;
}
3.  1787. Turn for MEGA

题意:有一个叫做"MEGA"的路口,给出这个路口每分钟可以通过车的数量k,和过去的时间n。接着再给出从1~n分钟每分钟到达该路口的车的数量a[i](这里a[1]表示在第1分钟内到达的车辆为a[1]个)。问最后一分钟该路口还剩多少车?

思路:刚看到这个题的时候,我是这样做的:k*n-(a[1]+a[2]+a[3]...a[n])。这里有个坑,比如k是5,n是3,然后a[]={0,0,6},5*3>6  很明显剩0辆,   但是实际情况是这样的:第1,2分钟时没有车,到第3分钟来了6辆,所以只能通过5辆,剩1辆。  按实际情况模拟即可AC

代码:

#include <iostream>

using namespace std;

int dp[101]={0}; //记录每分钟剩余的车辆

int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=0;i<k;i++)
    {
        if(i>0)
            dp[i]+=dp[i-1];  //加上前一分钟剩余的
        int temp;
        cin>>temp;
        dp[i]+=temp-n;
        if(dp[i]<0)
            dp[i]=0;   //剩余的车辆只能>=0
    }
    cout<<dp[k-1]<<endl;

    return 0;
}
4.  1788. On the Benefits of Umbrellas

题意:下雨天,公交车站,有n个女孩和m个男孩,每个男孩手里都有一把伞,而女孩手里没有。并且每个女孩都有一个怒气值i,男孩有一个怒气系数j。他们都要回学校,那么问题来了:如果没有男孩给某个女孩打伞,这个女孩会获得对应的怒气值,如果没有女孩和某个男孩作伴回去,那么这个男孩也会获得一个怒气值anger(anger=已经有女孩作伴的男孩的数量*自身的怒气系数)。问最后男女怎么匹配使得怒气总和最小,并输出这个值。

自己的思路:先按照怒气值从大到小排序,如果n>m,计算后面几个没有匹配的女孩的怒气和,输出即可。

如果n<m,暴力 从匹配1对~n对,依次算出怒气和,然后更新出最小值,输出即可。

代码:

#include <iostream>
#include <algorithm>
using namespace std;

const int M=101;

bool compare(int a,int b)
{
    return a>b;
}

int a[M],b[M];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>a[i];
    for(int j=0;j<m;j++)
        cin>>b[j];
    sort(a,a+n,compare);
    sort(b,b+m,compare);
    int mini=1000000000;
    if(m>n)
    {
        for(int t=0;t<=n;t++)  //t是匹配对数
        {
            int ans=0;
            for(int i=t;i<m;i++)
            {
                ans+=b[i]*t;
            }
            for(int i=t;i<n;i++)  //计算怒气和
                ans+=a[i];
            if(mini>=ans)
                mini=ans;    //更新最小值
        }
        cout<<mini<<endl;
    }
   else
    {
        int ans3=0;
        for(int k=m;k<n;k++)
            ans3+=a[k];
        cout<<ans3<<endl;
    }
    return 0;
}
5.   1789. Searching for the Dodecahedron

题意:有n个盒子,从1~n编号。其中一个盒子里藏着宝藏(treasure),你每次只能翻开一个盒子,但是宝藏会在你翻开后向左或者向右移动一个位置。问按照什么顺序翻盒子一定能找出宝藏,并输出这个顺序。

思路:假设宝藏在奇数号盒子里,从1~n依次找一遍肯定能找到。没有找到说明宝藏在偶数号盒子里,恰好跳过。这样的话,分两种情况。  

第一种情况:n为奇数,按最坏的情况(宝藏在偶数号盒子里),先从1~n翻一遍,由于n为奇数,宝藏就会跑到奇数号盒子里,再从1~n翻一遍即可。  

第二种情况:n为偶数,也按最坏的情况(宝藏在偶数号盒子里),我们可以先翻开1号盒子,使宝藏跑到奇数号盒子里,然后在从1~n扫荡一遍即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;


int n;
vector<int> v;
int main()
{
    while(cin>>n)
    {
        v.clear();
        for(int i=1; i<=n; i++)
            v.push_back(i);
        if(n%2==0) v.push_back(1);   //n为偶数,先放个1
        for(int i=1; i<=n; i++)     //再接着放1~n
            v.push_back(i);


        int len=v.size();
        cout<<len<<endl;
        for(int i=0; i<len; i++)
        {
            if(i) cout<<" ";
            cout<<v[i];
        }

        puts("");
    }


    return 0;
}
6.   1792. Hamming Code

题意:有四个圆(编号I,II, III, IV),位置摆放如下图,相交部分编号(1,2,3),这7部分每块的值只能为0或1。这四个圆相交的部分(比如3号)的值肯定是包含该部分的圆的值的和mod2。(比如Value[3]=(Value[I]+Value[II]+Value[IV])%2,Value[2]=(Value[I]+Value[III]+Value[IV])%2,and so on)。那么问题来了:给你这7部分的值,但有一位是错误的,要求你找出哪位是错的,把正确的输出。

思路:暴力即可,依次把每位的值换一下(0变1,1变0),再计算是否正确。如果不行再还原该值,继续尝试下一位。

代码:

#include <iostream>
#include <cstdio>
using namespace std;

int a[10]= {0};

bool ok(int a1,int a2,int a3,int a4,int a5,int a6,int a7)
{
    if((a1+a2+a4)%2!=a7) return false;
    if((a2+a3+a4)%2!=a5) return false;
    if((a1+a3+a4)%2!=a6) return false;
    return true;

}

int main()
{

    for(int i=0; i<7; i++)
        cin>>a[i];

    int flag=0;
        if(ok(a[0],a[1],a[2],a[3],a[4],a[5],a[6]))
        {
            flag=1;
            for(int i=0; i<7; i++)
            {
                printf("%d%c",a[i],i==6?'
':' ');
            }

        }
    if(flag==0)
    for(int i=0;i<7;i++)
    {


        a[i]^=1;
        if(ok(a[0],a[1],a[2],a[3],a[4],a[5],a[6]))
        {


            for(int i=0; i<7; i++)
            {
                printf("%d%c",a[i],i==6?'
':' ');
            }
            break;

        }
        a[i]^=1;
    }

    return 0;
}
7.  1793. Tray 2

题意:给你一个盘子和两只碗,盘子长宽高分别是a,b,d。第一只碗的下圆面半径r1,上圆半径r2,第二只碗下圆半径p1,上圆半径p2。两只碗高度都为h。问是否能将这两只碗放到这个盘子里,要求碗底都必须挨着盘子。可以的话输出YES,否则输出NO。

思路:高中数学,计算即可。这样放(俯视图)

 代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
double r1,r2,w1;
double p1,p2,w2;
double a,b,d,h;

struct point   //计算俩圆点距离的时候需要用坐标系
{
    double x;
    double y;
} A,B;

double dis(struct point A,struct point B)
{
    return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}

void yes()
{
    puts("YES");
}
void no()
{
    puts("NO");
}

int main()
{

    while(cin>>a>>b>>d>>r1>>r2>>p1>>p2>>h)
    {



        if(a<b) swap(a,b);
        w1=r2;
        w2=p2;
        if(h>d)
        {
            w1=r1+d*(r2-r1)/h;
            w2=p1+d*(p2-p1)/h;
        }
        if(w1<w2)
            swap(w1,w2);
        if(w1*2>b)   //先判断碗的直径是否大于盘子宽度
        {
            no();
            continue;
        }
        A.x=w1;
        A.y=w1;
        B.x=a-w2;
        B.y=b-w2;
        if(dis(A,B)>=(r2+p2)*(r2+p2))
        {
            yes();
        }
        else
            no();




    }
    return 0;
}
8.   1796. Amusement Park

题意:老师让孩子去买票,有面值为10, 50, 100, 500, 1000, 和 5000 的卢比(RMB和rouble都一样啦..),再告诉你每张票的价格price,老师只给孩子钱了,但没说要买几张。你需要计算出老师可能要买几张。

输入:这几种面额卢比的数量 和 票的价格。

输出:先几种情况,再输出每种情况分别买几张

思路:先看有没有和票价一样的卢比,如果有那肯定只有一种情况,就是用全部的钱去买票。如果面额最小的比票价还大,那么把面额最小的减去一张,计算最小值,再计算最大值,输出即可。

代码:

#include <iostream>

using namespace std;

int num[6];
int value[6]={10,50,100,500,1000,5000};
int main()
{
    int sum=0;
    for(int i=0;i<6;i++)
    {
        cin>>num[i];
        sum+=num[i]*value[i];
    }
    int price;
    cin>>price;
    int mi;

    for(int i=0;i<6;i++)
    {
        if(num[i]>0)
        {
            mi=i;
            break;
        }
    }
    if(value[mi]!=price)
    {
        int pre=sum-value[mi];
        int minnum=pre/price+1;
        int maxnum=sum/price;
        cout<<maxnum-minnum+1<<endl;
        for(int i=minnum;i<=maxnum;i++)
            cout<<i<<" ";
        cout<<endl;
    }
    else
    {
        cout<<1<<endl;
        cout<<sum/price<<endl;
    }

    return 0;
}
人生如修仙,岂是一日间。何时登临顶,上善若水前。
原文地址:https://www.cnblogs.com/f-society/p/5691783.html