暑假训练第二期---思维题2

A - Slime Combining
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

CodeForces 618A
Description
Your friend recently gave you some slimes for your birthday. You have n slimes all initially with value 1.

You are going to play a game with these slimes. Initially, you put a single slime by itself in a row. Then, you will add the other n - 1 slimes one by one. When you add a slime, you place it at the right of all already placed slimes. Then, while the last two slimes in the row have the same value v, you combine them together to create a slime with value v + 1.

You would like to see what the final state of the row is after you’ve added all n slimes. Please print the values of the slimes in the row from left to right.

Input
The first line of the input will contain a single integer, n (1 ≤ n ≤ 100 000).

Output
Output a single line with k integers, where k is the number of slimes in the row after you’ve finished the procedure described in the problem statement. The i-th of these numbers should be the value of the i-th slime from the left.

Sample Input
Input
1
Output
1
Input
2
Output
2
Input
3
Output
2 1
Input
8
Output
4
Hint
In the first sample, we only have a single slime with value 1. The final state of the board is just a single slime with value 1.

In the second sample, we perform the following steps:

Initially we place a single slime in a row by itself. Thus, row is initially 1.

Then, we will add another slime. The row is now 1 1. Since two rightmost slimes have the same values, we should replace these slimes with one with value 2. Thus, the final state of the board is 2.

In the third sample, after adding the first two slimes, our row is 2. After adding one more slime, the row becomes 2 1.

这是一道类似于2048小游戏的题目,只不过2048是遇到相同的变为两倍,这里是加1,我在这里使用是递归的方法,注意递归基的判断,具体见代码;

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
void fun(int n)
{
    int m=1;
    int cnt=0;
    while(m<n)
    {
        m*=2;
        cnt++;
    }
    if(n==m)
    {
        printf("%d",cnt+1);
        return;//递归基
    }
    printf("%d ",cnt);
    int temp=n-m/2;
    fun(temp);
}
int main()
{
    int n;
    scanf("%d",&n);
    fun(n);
    return 0;
}


B - Robot Sequence

CodeForces 626A

Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u

Description
Calvin the robot lies in an infinite rectangular grid. Calvin’s source code contains a list of n commands, each either ‘U’, ‘R’, ‘D’, or ‘L’ — instructions to move a single square up, right, down, or left, respectively. How many ways can Calvin execute a non-empty contiguous substrings of commands and return to the same square he starts in? Two substrings are considered different if they have different starting or ending indices.

Input
The first line of the input contains a single positive integer, n (1 ≤ n ≤ 200) — the number of commands.

The next line contains n characters, each either ‘U’, ‘R’, ‘D’, or ‘L’ — Calvin’s source code.

Output
Print a single integer — the number of contiguous substrings that Calvin can execute and return to his starting square.

Sample Input
Input
6
URLLDR
Output
2
Input
4
DLUU
Output
0
Input
7
RLRLRLR
Output
12
Hint
In the first case, the entire source code works, as well as the “RL” substring in the second and third characters.

Note that, in the third case, the substring “LR” appears three times, and is therefore counted three times to the total result.

这个题由于数据量小,直接枚举,第一层循序是开始元素的遍历,第二层循环是结束元素的遍历,满足条件的子串是从开始到结束时出现的向左走的步数等于向右走的步数,同理向上走的步数是等于向下走的。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char a[205];
int ans=0;
int main()
{
    int n;
    scanf("%d",&n);
    getchar();
    gets(a);
    for(int i=0;i<n;i++)
    {
        int r=0,l=0,u=0,d=0;
        for(int j=i;j<n;j++)
        {
            if(a[j]=='R')r++;
            if(a[j]=='L')l++;
            if(a[j]=='U')u++;
            if(a[j]=='D')d++;
            if(r==l&&u==d)ans++;
        }
    }
    printf("%d",ans);
    return 0;
}


C - Simple Strings

CodeForces 665C

Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u

Description
zscoder loves simple strings! A string t is called simple if every pair of adjacent characters are distinct. For example ab, aba, zscoder are simple whereas aa, add are not simple.

zscoder is given a string s. He wants to change a minimum number of characters so that the string s becomes simple. Help him with this task!

Input
The only line contains the string s (1 ≤ |s| ≤ 2·105) — the string given to zscoder. The string s consists of only lowercase English letters.

Output
Print the simple string s’ — the string s after the minimal number of changes. If there are multiple solutions, you may output any of them.

Note that the string s’ should also consist of only lowercase English letters.

Sample Input

Input
aab

Output
bab

Input
caaab

Output
cabab

Input
zscoder

Output
zscoder

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char s[200005];
int main()
{
    scanf("%s",s);
    int l= strlen(s);
    for(int i=1;i<=l;i++)
    {
        if(s[i]==s[i-1])
        {
            for(int j=0;j<26;j++)
            {
                if(s[i-1]==j+'a'||s[i+1]==j+'a')
                    continue;
                s[i]=char(j+'a');
                break;
            }
        }
    }
    printf("%s\n",s);
    return 0;
} 


D - Restoring Painting

Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u

CodeForces 675B
Description
Vasya works as a watchman in the gallery. Unfortunately, one of the most expensive paintings was stolen while he was on duty. He doesn’t want to be fired, so he has to quickly restore the painting. He remembers some facts about it.

The painting is a square 3 × 3, each cell contains a single integer from 1 to n, and different cells may contain either different or equal integers.
The sum of integers in each of four squares 2 × 2 is equal to the sum of integers in the top left square 2 × 2.
Four elements a, b, c and d are known and are located as shown on the picture below.
这里写图片描述
Help Vasya find out the number of distinct squares the satisfy all the conditions above. Note, that this number may be equal to 0, meaning Vasya remembers something wrong.

Two squares are considered to be different, if there exists a cell that contains two different integers in different squares.

Input
The first line of the input contains five integers n, a, b, c and d (1 ≤ n ≤ 100 000, 1 ≤ a, b, c, d ≤ n) — maximum possible value of an integer in the cell and four integers that Vasya remembers.

Output
Print one integer — the number of distinct valid squares.

Sample Input
Input
2 1 1 1 2
Output
2
Input
3 3 1 2 3
Output
6

这是一道数学推理题,首先设棋盘中剩下的五个位置依次为x1,x2,x3,x4,x5;
首先确定根据条件可知,x3是任意取值的,可先不管,然后确定由x1可以得到x2,x4,x5,所以只需遍历x1,看是否满足x2,x4,x5都在1-n的范围内即可;最后再乘上n即可。

代码如下:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
ll n,a,b,c,d,ans=0;
int main()
{
    scanf("%I64d%I64d%I64d%I64d%I64d",&n,&a,&b,&c,&d);
    for(int i=1;i<=n;i++)
    {
        ll x2=i+b-c;
        ll x4=i+a-d;
        ll x5=i+a+b-c-d;
        if(x2<=n&&x2>=1&&x4<=n&&x4>=1&&x5>=1&&x5<=n)
        ans++;
    }   
    printf("%I64d",ans*n);
    return 0;
} 


E - Guest From the Past

CodeForces 625A

Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u

Description
Kolya Gerasimov loves kefir very much. He lives in year 1984 and knows all the details of buying this delicious drink. One day, as you probably know, he found himself in year 2084, and buying kefir there is much more complicated.

Kolya is hungry, so he went to the nearest milk shop. In 2084 you may buy kefir in a plastic liter bottle, that costs a rubles, or in glass liter bottle, that costs b rubles. Also, you may return empty glass bottle and get c (c < b) rubles back, but you cannot return plastic bottles.

Kolya has n rubles and he is really hungry, so he wants to drink as much kefir as possible. There were no plastic bottles in his 1984, so Kolya doesn’t know how to act optimally and asks for your help.

Input
First line of the input contains a single integer n (1 ≤ n ≤ 1018) — the number of rubles Kolya has at the beginning.

Then follow three lines containing integers a, b and c (1 ≤ a ≤ 1018, 1 ≤ c < b ≤ 1018) — the cost of one plastic liter bottle, the cost of one glass liter bottle and the money one can get back by returning an empty glass bottle, respectively.

Output
Print the only integer — maximum number of liters of kefir, that Kolya can drink.

Sample Input
Input
10
11
9
8
Output
2
Input
10
5
6
1
Output
2
Hint
In the first sample, Kolya can buy one glass bottle, then return it and buy one more glass bottle. Thus he will drink 2 liters of kefir.

In the second sample, Kolya can buy two plastic bottle and get two liters of kefir, or he can buy one liter glass bottle, then return it and buy one plastic bottle. In both cases he will drink two liters of kefir.

数学思维题,当(b-c)< a && n> b时注意在要先买一份,再算差价,最后用余数去买a;

代码如下:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int main()
{
    ll n,a,b,c,ans;
    scanf("%I64d%I64d%I64d%I64d",&n,&a,&b,&c);
    ans=0;
    if(n>=b&&a>b-c)
    {
        ans+=(n-b)/(b-c)+1;
        n-=ans*(b-c);
    }
    ans+=n/a;
    printf("%I64d\n",ans);
    return 0;
} 


F - Not Equal on a Segment

CodeForces 622C
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u

Description
You are given array a with n integers and m queries. The i-th query is given with three integers li, ri, xi.

For the i-th query find any position pi (li ≤ pi ≤ ri) so that api ≠ xi.

Input
The first line contains two integers n, m (1 ≤ n, m ≤ 2·105) — the number of elements in a and the number of queries.

The second line contains n integers ai (1 ≤ ai ≤ 106) — the elements of the array a.

Each of the next m lines contains three integers li, ri, xi (1 ≤ li ≤ ri ≤ n, 1 ≤ xi ≤ 106) — the parameters of the i-th query.

Output
Print m lines. On the i-th line print integer pi — the position of any number not equal to xi in segment [li, ri] or the value  - 1 if there is no such number.

Sample Input
Input
6 4
1 2 1 1 3 5
1 4 1
2 6 2
3 4 1
3 4 2
Output
2
6
-1
4

这个题听学长讲的很精妙的一个方法,用一个数组pre[]来进行预处理记录,记录的是从当前下标开始向前的第一个和当前数不同的数的下标;
这样在之后询问的时候就不用去搜索了,直接判断最后一位r,如果是不同的输出a[r]如果相同就判断l是否在pre[r]前面,如果在就输出pre[r],不在就是-1,表示区间里没有与x不同的数;

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[200005],pre[200005];

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    a[0]=a[n+1]=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(i==1)pre[i]=0;
        else pre[i]=(a[i]==a[i-1]?pre[i-1]:i-1);
    }
    while(m--)
    {
        int l,r,x;
        scanf("%d%d%d",&l,&r,&x);
        if(a[r]!=x)printf("%d\n",r);
        else 
        {
            if(pre[r]>=l)printf("%d\n",pre[r]);
            else printf("-1\n");            
        }
    }
    return 0;
}

仅代表个人观点,欢迎交流探讨!

这里写图片描述

图自P站 id=57707529

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值