UESTC ACM训练题二

A-Clock(Problem ID 49 数学)

Standard Input
The first line of the input contains one integer T, which indicate the number of test cases. Each test case contains one indicating the time on hhb’s clock in the form of HH:MM. (0≤HH<24,0≤MM<60)

Standard Output
One line for each test case contains only one number indicating the answer. An integer or an irreducible fraction indicated the degree between hour finger and minute finger.

Samples

InputOTput
10
00:00

Note

  • 时针每分钟走0.5°,分针每分钟走6°
  • 24h/12h
  • 夹角取锐角
#include<bits/stdc++.h>

using namespace std;

int main()
{
    int T;
    char time[6]={0};
    scanf("%d",&T);
    cin.getline(time,5);
    while (T--)
    {
        int hour,minute;
        float degree;
        cin.getline(time,6);

        hour=10*(time[0]-'0')+time[1]-'0';
        minute=10*(time[3]-'0')+time[4]-'0';
        if(hour>=12) hour-=12;
        degree=30*hour-5.5*minute;
        if(degree<0) degree=-degree;
        if(degree>180) degree=360-degree;
        if(degree==(int)degree) printf("%.0f\n",degree);
        else printf("%.0f/2\n",2*degree);
    }
    return 0;
}

B-论文搜素(Problem ID 158 字符串处理)

allenlowesy纠结了,他不可能把所有的论文都看了来确定是否有用。于是他假设,如果论文的标题中有一个单词是关键词(大小写也要一致),那么这篇论文是有用的。

Standard Input
含多组测试数据,输入首先是一个整数T表示测试数据组数(T≤20)。
每组数据开始为一个整数N(N≤100),表示检索到的论文数
接下来1行是allenlowesy搜索的关键词,长度不超过20,只包括小写字母和大写字母。
接下来N行,每一行是一个论文的标题,长度不超过100,只包括小写字母、大写字母和空格

Standard Output
每组数据输出一个整数M,表示allenlowesy认为有用的论文数。
如果没有一篇论文的标题包含有关键词,则输出Do not find。
在每组输出结果后再输出一个空行。

Samples

InputOTput
31
2
fiber1
optical fiber
optical FiberDo not find
3
Sensors
Optical Fiber Sensing in Mechanical Measurement
A New Approach to Build AdvancedSensors
Comparison to different Sensors
2
xmm
lcy
silentsky

Note

  • 输入数字和字符之间用getchar();吸收空格
  • 判断有"XX", " XX ", " XX"三种情况
  • 使用s.find()函数若找出字符串判断不合格要继续向后搜索直至末尾。例如:fiberoptical fiber。
#include<bits/stdc++.h>

using namespace std;
int search_word(string key ,string word)
{
    int len,pos=0;
    len=key.size();
    while(pos+1)
    {
        pos=word.find(key,pos);
        if(pos==0)
        {
            if(word[pos+len]==' '||word[pos+len]=='\0')
                return 1;
            else pos+=len;
        }
        else if(pos>0)
        {
            if(word[pos-1]==' '&&(word[pos+len]==' '||word[pos+len]=='\0'))
                return 1;
            else pos+=len;
        }
    }
    return 0;
}


int main()
{
    int T,N,n;
    string key,word;
    scanf("%d",&T);
    while (T--)
    {
        int ct=0;;
        scanf("%d",&N);
        getchar();
        getline(cin,key);
        cout<<"n:  "<<n<<endl;
        while(N--)
        {
            getline(cin,word);
            if(search_word(key,word)) ct++;
        }
        if(ct) printf("%d\n\n",ct);
        	else printf("Do not find\n\n");
    }
    return 0;
}

C-Passing the Ball(Problem ID 1521 数学)

Note

  • 这实际上是一个概率论中常见的问题,每次的传球结果由于上一次的传球结果相关,是一个递归的关系。(具体推导见下图)
    在这里插入图片描述

Code

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int N,M,x;
	cin>>N>>M;
    x=(int)pow(N-1,M)+(int)pow(-1,M)*(N-1);
    printf("%d",x/N);
    return 0;
}

D-Little_Pro的driver朋友们和他的魔法(Problem ID 1514 数学)

Littlte_Pro 是一个聪明的小司机,他想让这些队列的good driver、baddriver交替出现。我们的 Little_Pro 同时也是一位大魔法师. 每一次施法,他可以在一瞬间交换2个driver的在队列中的位置, 或者改变driver叔叔的性质(把一个good driver 变成 bad driver 或者把一个bad driver 变成 good driver)。
请你帮忙找到最少的施法次数,从而使这些driver朋友们在队列中good driver、bad driver交替出现。

Standard Input
第一行输入一个 integer n (1 ≤ n ≤ 100,000) — 表示drivers的数量.
第二行输入一个包含n个元素的字符串, 其中包括字符’1’ 和字符 ‘0’,其中’1’ 代表 bad driver、 ‘0’ 代表 good driver.

Standard Output
输出一个 integer — Little_Pro 需要的最少的施法次数,从而使这些driver在队列中good driver、bad driver交替出现。

Samples

InputOTput
51
01100
52
11111
30
010

Note

  • 找到10交替或01交替,奇偶数位负位的次数m,n(不妨设m<n),则是魔法次数为m(交换位置)+(n-m)(10变换)=n,再找出不同交替顺序施展魔法次数少的输出。
  • 10交替正位及01交替负位

Code

#include <bits/stdc++.h>

using namespace std;

int magic(int a,int b)
{
    return a>b? a:b;
}

int magic_sum(int a,int b)
{
    return a<b? a:b;
}

int main()
{
    int n,i,sum;
    int flag[4]={0};
    scanf("%d",&n);
    getchar();
    char c[n+1]={0};
    cin.getline(c,n+1);
    for(i=0;i<n;i++)
    {
        if(i%2)
        {
            if(c[i]=='1') flag[1]++;
            else flag[3]++;
        }
        else
        {
            if(c[i]=='0') flag[0]++;
            else flag[2]++;
        }
    }
    sum=magic_sum(magic(flag[0],flag[1]),magic(flag[2],flag[3]));
    cout << sum << endl;

    return 0;
}

E-8球胜负(eight)(Problem ID 24 字符串处理)

Note

  • 进行简单字符串处理和情况判断

Code

#include <bits/stdc++.h>

using namespace std;
#define N 16

int findR(char c[],int n)
{
    int i,sum=0;
    for(i=0;i<n-1;i++)
        if(c[i]=='R') sum++;
    return sum;

}


int main()
{
    int n;
    char c[N]={0};
    while(1)
    {
        int r=0;
        memset(c,0,sizeof(char));
        scanf("%d",&n);
        if(n==0) break;
        getchar();
        cin.getline(c,N);

        r=findR(c,n);
        if(c[n-1]=='B')
        {
            if(n>6&&r==7) printf("Red\n");
            else printf("Yellow\n");
        }
        else if(c[n-1]=='L')
        {
            if(n>6&&r==n-8) printf("Yellow\n");
            else printf("Red\n");
        }
    }
    return 0;
}

F-点球大战(penalty)(Problem ID 25 字符串处理)

Note

  • 用s.rfind()从字符串尾部开始检测" no good"即可。

Code

#include <bits/stdc++.h>

using namespace std;

int verdict(string s)
{
    int pos,len;
    len=s.size();
    pos=s.rfind(" no good",len-1);
    if(pos==len-8) return pos;
    else return -1;
}


int main()
{
    while(1)
    {
        int i,n;
        int flag=0,status=0;
        string l,a,b,s;
        char score1='0' ,score2='0',turn='1';
        scanf("%d",&n);
        getchar();
        i=n;
        if(n==0) break;
        while(n--)
        {
            getline(cin,s);
            status=verdict(s);
            switch(status)
            {
                case -1:{   if(flag) {  b.append("O ");
                                        score2++;
                                        flag=!flag; }
                            else {  a.append("O ");
                                    score1++;
                                    l.push_back(turn++);
                                    l.push_back(' ');
                                    flag=!flag; }
                        }break;
                default:{   if(flag) {  b.append("X ");
                                        flag=!flag; }
                            else {  a.append("X ");
                                    l.push_back(turn++);
                                    l.push_back(' ');
                                    flag=!flag; }
                        }break;
            }
        }
        if(i%2) b.append("- ");
        l.append("Score");
        a.push_back(score1);
        b.push_back(score2);
        cout<<l<<endl;
        cout<<a<<endl;
        cout<<b<<endl;
    }
    return 0;
}

G-简单的数学题(Problem ID 1513 数学)

Note

  • 根据同余定理,一个数除以9的余数就是这个数所有位上的数之和除以9的余数,也就是说这个数无论如何排列它对于9的余数都是相同的,找出这个数从小到大重新排列组成的数即可。

Code

#include <bits/stdc++.h>

using namespace std;

void swapc(char *p,char *q)
{
    char temp;
    temp=*q;
    *q=*p;
    *p=temp;
}

void maopao(char c[])
{
    int len=strlen(c);
    int i,j;
    for(i=0;i<len;i++)
        for(j=0;j<len-i-1;j++)
            if(c[j]>c[j+1]) swapc(&c[j],&c[j+1]);
}

int main()
{
    char c[1001]={0};
    scanf("%s",c);
    maopao(c);
    cout << c ;
    return 0;
}

H-P酱的冒险旅途(Problem ID 758 字符串处理 )

Note

  • 判断行动方位,在给出字符串序列里搜索需要的步数即可。

Code

#include <bits/stdc++.h>

using namespace std;
#define N 100001
int direction(int x,int y)
{
    if(x>0&&y>0)return 1;
    if(x>0&&y<0)return 3;
    if(x<0&&y<0)return 5;
    if(x<0&&y>0)return 7;
    if(x==0&&y>0)return 0;
    if(x>0&&y==0)return 2;
    if(x==0&&y<0)return 4;
    if(x<0&&y==0)return 6;
}

int main()
{
    int T;
    char c[N]={0};
    scanf("%d",&T);
    while(T--)
    {
        int x,y,t;
        int dir,i,a=0,b=0,time=-1;
        memset(c,0,sizeof(char));
        scanf("%d%d%d",&x,&y,&t);
        getchar();
        scanf("%s",c);
        dir=direction(x,y);
        switch(dir)
        {
            case 0:{
                for(i=0;i<t;i++)
                {
                    if(b==y)
                    {
                        time=i;
                        break;
                    }
                    if(c[i]=='U'&&b<y) b++;
                }
            }break;
            case 1:{
                for(i=0;i<t;i++)
                {
                    if(a==x&&b==y)
                    {
                        time=i;
                        break;
                    }
                    if(c[i]=='R'&&a<x) a++;
                    else if(c[i]=='U'&&b<y) b++;
                }
            }break;
            case 2:{
                for(i=0;i<t;i++)
                {
                    if(a==x)
                    {
                        time=i;
                        break;
                    }
                    if(c[i]=='R'&&a<x) a++;
                }
            }break;
            case 3:{
                for(i=0;i<t;i++)
                {
                    if(a==x&&b==y)
                    {
                        time=i;
                        break;
                    }
                    if(c[i]=='R'&&a<x) a++;
                    else if(c[i]=='D'&&b>y) b--;
                }
            }break;
            case 4:{
                for(i=0;i<t;i++)
                {
                    if(b==y)
                    {
                        time=i;
                        break;
                    }
                    if(c[i]=='D'&&b>y) b--;
                }
            }break;
            case 5:{
                for(i=0;i<t;i++)
                {
                    if(a==x&&b==y)
                    {
                        time=i;
                        break;
                    }
                    if(c[i]=='L'&&a>x) a--;
                    else if(c[i]=='D'&&b>y) b--;
                }
            }break;
            case 6:{
                for(i=0;i<t;i++)
                {
                    if(a==x)
                    {
                        time=i;
                        break;
                    }
                    if(c[i]=='L'&&a>x) a--;
                }
            }break;
            case 7:{
                for(i=0;i<t;i++)
                {
                    if(a==x&&b==y)
                    {
                        time=i;
                        break;
                    }
                    if(c[i]=='L'&&a>x) a--;
                    else if(c[i]=='U'&&b<y) b++;
                }
            }break;
        }
        printf("%d\n",time);
    }
    return 0;
}

I-铁路(Problem ID 762 数学)

Note

  • 当一个城市可修铁路数k 大于等于 n-1时,任意两个城市都能联通,则可修铁路总数为n(n-1)/2。
  • 当一个城市可修铁路数k 小于 n-1时,每座城市都修满k条铁路 ,则可修铁路总数为n*k/2。
  • 特殊情况:当城市数为1或修铁路数为0时,可修铁路总数为0。

Code

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n ,k;
        scanf("%d%d",&n,&k);
        if(k==0||(n>2&&k==1)) printf("0\n");
        else if(k>n-2) printf("%d\n",n*(n-1)/2);
        else printf("%d\n",n*k/2);
    }
    return 0;
}

J-昊昊爱运动(Problem ID 1256 简单枚举)

Note

  • 先进行打表,记录所有可能的情况,再输出结果。

Code(代码遗失,参见网上开源代码)

#include <iostream>
#include<cstdio>
#include <cstring>
using namespace std;
#define N 2005
int a[N];
int ANS[N][N];
int vis[N];
int main()
{

    int n, m;
    scanf("%d %d",&n,&m);
    int ans = 0;
    for(int i = 1; i <= n; i++)
        scanf("%d",a+i);
    for(int i = 1; i <= n; i++)
    {
        memset(vis,0,sizeof(vis));
        ans = 0;
        for(int j = i; j <= n; j++)
        {
            if(vis[a[j]]==0)
            {
                ans++;
                vis[a[j]]++;
            }
            ANS[i][j] = ans;//第i天到第j天的种数
        }
    }
    int l, r, Q;
    cin>>Q;
    while(Q--)
    {
        scanf("%d %d",&l,&r);
        cout<<ANS[l][r]<<endl;
    }
    return 0;
}

K-人民币的构造(Problem ID 1264 数学)

Note

  • 假设目前可以表示的范围是 [1,P],再加一个数Q(Q>P),新增的可表示的范围为 [ Q-P,Q+P ],并且必须满足即有Q-P =P+1;即 Q=2P+1;新表示的范围即为[ 1,3P+1 ]。

Code

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

int main()
{
    int n;
    int tol=1,i=1;
    scanf("%d",&n);
    while(n>tol)
    {
        tol=3*tol+1;
        i++;
    }
    printf("%d\n",i);
    return 0;
}

L-倒推数组(Problem ID 759 数学)

Note

  • 长度为n的数组最小字典序为1到n的升序列,算出该序列的f值,即为最小的f值,如果f小于题目所给的值,只有修改最小字典序的最后一个值即可。

Code

using namespace std;

int main()
{
    int T,n,f,i,j;
    long sum=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&f);
        j=2*n-1;
        sum=0;
        for(i=1;i<=n;i++)
        {
            sum+=j*i;
            j-=2;
        }
        if(sum>f) printf("-1\n");
        else
        {
            for(i=1;i<n;i++)
            {
                printf("%d ",i);
            }
            printf("%ld\n",i+f-sum);
        }
    }
    return 0;
}

M-矩阵(Problem ID 1805 杂题)

Note

  • 矩阵(MXN)的每一行/列的乘积都有每一行/列最后一个元素决定。
  • 若K=1,则子阵(M-1)X (N-1) 中的元素时可以任意取,且设子阵所有元素的乘积为S 。第 i 行/列的最后一个元素的取值就是该行/列前面元素的积,则最后一行/列(除最后一个元素)的元素积为S,那么矩阵最后一个元素取S能同时保证最后一行/列的元素积为K。
  • 若K=1,第 i 行/列的最后一个元素的取值就是该行/列前面元素的积取反,则最后一行(除最后一个元素)的元素积为(-1)^(N-1) *S,最后一列(除最后一个元素)的元素积为(-1)^(M-1)*S。如果M和N的奇偶性不同,那么就无法满足要求。

Code

#include <stdio.h>

using namespace std;

int main()
{
    int n,m,k;
    scanf("%d%d%d",&m,&n,&k);
    if(k==-1&&(n+m)%2) printf("0");
    else printf("%d",1<<(n-1)*(m-1));
    return 0;
}

N-能否被3整除2(Problem ID 1939 数学)

Note

  • 找规律,从f(3)开始找第一个余数为0的数,若它前一个数的余数为0,则序列所有数都能被3整除,否则周期为4。

Code

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int a,b,m;
        scanf("%d%d%d",&a,&b,&m);
        int num[6]={a,b},pos;
        for(pos=2;pos<6;pos++)
        {
            num[pos]=num[pos-1]+num[pos-2];
            if(num[pos]%3==0) break;
        }
        while(m--)
        {
            long n;
            scanf("%ld",&n);
            if(num[pos-1]%3==0)
                printf("Yes\n");
            else if((n-pos)%4==0)
                printf("Yes\n");
            else printf("No\n");
        }
        printf("\n");
    }
    return 0;
}

O-门外的树(Problem ID 1969 简单枚举)

Note

  • 用一个较大的数组存储所有树的状态(1:保留;0:移走),最后遍历数组可得余下的树。

Code

int main()
{
    int t,m,a,b;
    int i,sum=0;
    scanf("%d%d",&t,&m);
    memset(w,1,sizeof(w));
    while(m--)
    {
        scanf("%d%d",&a,&b);
        for(i=a;i<=b;i++)
            w[i]=0;
    }
    for(i=0;i<=t;i++)
        if(w[i]) sum++;
    printf("%d",sum);
    return 0;
}

P-木杆上的蚂蚁(Problem ID 300 杂题)

Note

  • 对于杆上的蚂蚁,当两个蚂蚁碰头后,它们互换方向,但是我们仍然可以看成它们的方向没有改变,只是一只蚂蚁的路程让另外一只来走而已,所以对于每一只蚂蚁,如果不区分它们,那么它们的时间是可以求出来的,即它们所在的位置到终点的位移。由于每一只蚂蚁的相对位置没有改变,因此根据时间的先后和对应那只蚂蚁的方向,我们就知道了每只蚂蚁掉落的顺序。

Code

#include <bits/stdc++.h>
#define N 100
using namespace std;

struct ant_type
{
    int pos;
    char name[11];
} ants[N];

struct event_type
{
    int drop_time;
    char dir;
} events[N];

bool cmp_ant(const ant_type& p, const ant_type& q)
{
    return p.pos < q.pos;
}

bool cmp_event(const event_type& p, const event_type& q)
{
    return p.drop_time < q.drop_time;
}

int main()
{
    char dir[2];
    int i, k, n, L, R, T;
    scanf("%d", &T);
    for (k = 1; k <= T; k++)
    {
        scanf("%d%d", &n, &L);
        for (i = 0; i < n; i++)
        {
            scanf("%s%d%s", ants[i].name, &ants[i].pos, dir);
            events[i].dir = dir[0];
            events[i].drop_time = (dir[0] == 'L' ? ants[i].pos : L - ants[i].pos);
        }
        sort(ants, ants + n, cmp_ant);
        sort(events, events + n, cmp_event);
        printf("Case #%d:\n", k);
        L = 0;
        R = n - 1;
        for (i = 0; i < n; i++)
        {
            if (events[i].dir == 'L')
            {
                printf("%d %s\n", events[i].drop_time,ants[L].name);
                L++;
            }
            else
            {
                printf("%d %s\n", events[i].drop_time,ants[R].name);
                R--;
            }
        }
    }
    return 0;
}

Q-输出前m大的数据(Problem ID 2074 简单枚举)

Note

  • 创建一个较大的数组,对应下标(数+500000)的元素存储该数的频数,最后从后往前遍历输出m个有效数据。

Code

#include <bits/stdc++.h>

using namespace std;

#define N 500000
int a[2*N+5];

int main()
{
    int T,n,m,t,i;
    scanf("%d",&T);
    while(T--)
    {
        memset(a,0,sizeof(a));
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
        {
            scanf("%d",&t);
            a[t+N]++;
        }
        for(i=2*N;m>0&&i>=0;)
        {
            if(a[i]!=0)
            {
                printf("%d ",i-N);
                a[i]--;
                m--;
            }
            else
                i--;
        }
        printf("\n");
    }
    return 0;
}

R-Fly Through(Problem ID 100 杂题)

Note

  • 用数组a[i] 存储岩石高度大于等于i 的岩石数量。

Code

#include <bits/stdc++.h>

using namespace std;

#define N 100001
int a[N];

int main()
{
    int n,m,t,i;
    memset(a,0,sizeof(a));
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++)
    {
        scanf("%d",&t);
        a[t]++;
    }
    for(i=N-2;i>=1;i--)
    {
        a[i]+=a[i+1];
    }
    while(m--)
    {
        scanf("%d",&t);
        printf("%d\n",a[t]);
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值