Codeforces Round #224 (Div. 2)解题报告

A. Ksenia and Pan Scales
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Ksenia has ordinary pan scales and several weights of an equal mass. Ksenia has already put some weights on the scales, while other weights are untouched. Ksenia is now wondering whether it is possible to put all the remaining weights on the scales so that the scales were in equilibrium.

The scales is in equilibrium if the total sum of weights on the left pan is equal to the total sum of weights on the right pan.

Input

The first line has a non-empty sequence of characters describing the scales. In this sequence, an uppercase English letter indicates a weight, and the symbol "|" indicates the delimiter (the character occurs in the sequence exactly once). All weights that are recorded in the sequence before the delimiter are initially on the left pan of the scale. All weights that are recorded in the sequence after the delimiter are initially on the right pan of the scale.

The second line contains a non-empty sequence containing uppercase English letters. Each letter indicates a weight which is not used yet.

It is guaranteed that all the English letters in the input data are different. It is guaranteed that the input does not contain any extra characters.

Output

If you cannot put all the weights on the scales so that the scales were in equilibrium, print string "Impossible". Otherwise, print the description of the resulting scales, copy the format of the input.

If there are multiple answers, print any of them.

Sample test(s)
input
AC|T
L
output
AC|TL
input
|ABC
XYZ
output
XYZ|ABC
input
W|T
F
output
Impossible
input
ABC|
D
output
Impossible

      感觉还是太弱了,平时做题太少,思维方面的短板还是很多。最近得好好做点题练习。作为小白,还是得把基础打扎实,一步步慢慢来。

解题思路

         这道题属于比较简单的字符串处理题。首先将天平左右两边的字符串截取出来。然后计算出总的重量。如果总重量为奇数,那么无法使得天平平衡。所以为Impossible。

还有在未添加物体之前,已经有一边超过了总重量的一半,那么也是Impossible。其他情况下,只需要按照个数将两边的物体重量加到总重量的一半即可。

参考代码

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

const int maxn=1000100;

char str[maxn],str1[maxn];
int main()
{
    while(~scanf("%s",str))
    {
        int k1=strlen(str),a=0,b=0;
        int i=0;
        while(i<k1&&str[i]!='|')
           i++,a++;
        if(i<k1)
        {
            i++;
            while(i<k1)
                i++,b++;
        }
        scanf("%s",str1);
        int k2=strlen(str1);
        if((k2+k1-1)%2!=0)
            printf("Impossible\n");
        else
        {
            int t=(k1+k2-1)/2;
            if(a>t||b>t)
                printf("Impossible\n");
            else
            {
                int t1=t-a,t2=t-b;
                for(int i=0;i<a;i++)
                    printf("%c",str[i]);
                for(int i=0;i<t1;i++)
                    printf("%c",str1[i]);
                printf("|");
                for(int i=a+1;i<k1;i++)
                   printf("%c",str[i]);
                for(int i=t1;i<k2;i++)
                    printf("%c",str1[i]);
                printf("\n");

            }
        }

    }
}</span>


 

B. Number Busters
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Arthur and Alexander are number busters. Today they've got a competition.

Arthur took a group of four integers a, b, w, x (0 ≤ b < w, 0 < x < w) and Alexander took integer с. Arthur and Alexander use distinct approaches to number bustings. Alexander is just a regular guy. Each second, he subtracts one from his number. In other words, he performs the assignment: c = c - 1. Arthur is a sophisticated guy. Each second Arthur performs a complex operation, described as follows: if b ≥ x, perform the assignment b = b - x, if b < x, then perform two consecutive assignments a = a - 1; b = w - (x - b).

You've got numbers a, b, w, x, c. Determine when Alexander gets ahead of Arthur if both guys start performing the operations at the same time. Assume that Alexander got ahead of Arthur if c ≤ a.

Input

The first line contains integers a, b, w, x, c (1 ≤ a ≤ 2·109, 1 ≤ w ≤ 1000, 0 ≤ b < w, 0 < x < w, 1 ≤ c ≤ 2·109).

Output

Print a single integer — the minimum time in seconds Alexander needs to get ahead of Arthur. You can prove that the described situation always occurs within the problem's limits.

Sample test(s)
input
4 2 3 1 6
output
2
input
4 2 3 1 7
output
4
input
1 2 3 2 6
output
13
input
1 1 2 1 1
output
0
解题思路

       这道题刚开始看的时候感觉很简单,就是简单的循环而已。但是做了一下发现超时了。。然后想到题目中说的保证结果总是存在的。于是想到肯定有规律。便用暴力的方法来寻找循环的周期。由于w的最大值是1000,而b和x都比w要小。所以整个b的值循环的最大周期也就是1000左右。所以每次进行计算时我先循环2000次。然后在这2000个数中暴力寻找周期。这样复杂度还是比较低的。然后就可以通过周期函数的特点在O(1)的时间内得到答案。通过对周期长度的枚举,然后暴力求出周期。在res数组中记录的是b与x的关系。如果b>=x,那么res[i]=1。反之,res[i]=0。这样做的原因是如果要使得c减小直到满足c<=a,也就是c减小的幅度要大于a减小的幅度才行。在b<x时,c--,a--;这个时候,c与a之间的差值是不会改变的,而只有在b>=x时,c--,而a的值保持不变,这样他们的差值才会不断减小。然后计算在出一个周期内,c相对于a减小的值shu(相对的减小差值)。然后算一下c-a这个值是一个周期中shu值的多少倍。即需要多少个周期。但是在这里还是有一些坑的。要先判断c-a能否被shu整除。如果能够整除,周期个数为m。先需要计算出m-1个周期内总的时间。然后再求出最后一个周期内需要多少时间。最后一个周期内需要逐步遍历,然后当res[i]==1的个数达到shu的时候此时对应的i,也就是剩下的时间。此外,如果c-a不能够整除shu的话,就先计算(c-a)/shu个周期内的总时间。然后计算最后余数所需要的时间。然后将两个加起来就可以了。

参考代码

#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;

const int maxn=1000100;

int res[maxn];
int main()
{
   ll a,b,w,x,c;
   while(~scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&w,&x,&c))
   {
       ll ans=0,i=1;
       ll T=0,shu=0;
       if(c<=a)
       {
           printf("0\n");
           continue;
       }
       while(i<=2000)
       {
           if(b>=x)  res[i]=1,b-=x;
           else res[i]=0,b=w-(x-b);
           i++;
       }
       for(int i=1;i<=1000;i++)
       {
           bool flag=1;
            for(int j=1; j<=1000; j++)
                if(res[j]!=res[j+i])
                    flag=0;
            if(flag)
            {
                T=i;
                break;
            }
       }
       for(int i=1;i<=T;i++)
        if(res[i]==1)
          shu++;
       ll t,t1=0,num1=0;
       if((c-a)%shu==0)
           t=((c-a)/shu-1)*T;
       else t=(c-a)/shu*T;
       ll num=(c-a)%shu;
       if(num==0) num=shu;
       for(ll i=1;i<=T;i++)
       {
           if(res[i]==1)
               t1++;
           if(t1==num)
           {
               num1=i;
               break;
           }
       }
       printf("%I64d\n",t+num1);
   }
}

 刚刚看了题解说还可以二分搜索。 

#include<iostream>
using namespace std;
int a, b, w, x, c, add;
long long res=0, tpow=1;
long long nrem(long long sec) {
	if(b >= sec*x) return sec;
	long long nadd= (sec*x - b - 1) / (add + x) + 1;
	return sec-nadd;
}
int main() {
	cin >> a >> b >> w >> x >> c;
	add = w-x;
	if(c <= a)
		cout << "0\n";
	else {
		while(nrem(tpow) < c-a)
			tpow *= 2;
		while(tpow > 0) {
			if(nrem(res + tpow) < c-a)
				res += tpow;
			tpow /= 2;
		}
		cout << res+1 << '\n';
	}
	return 0;
};
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

long long a, b, c, w, x;

long long cal1(long long t)
{
    long long d = b - x * t;
    if (d >= 0)
    {
        return a;
    }
    else
    {
        long long e = (-d + w - 1) / w;
        return a - e;
    }
}

long long cal2(long long t)
{
    return c - t;
}

bool check(long long t)
{
    return cal1(t) >= cal2(t);
}

int main()
{
    cin >> a >> b >> w >> x >> c;
    long long l = 0, r = 2000000000000ll;
    if (check(l))
    {
        cout << 0 << endl;
    }
    else
    {
        long long m;
        while (l < r)
        {
            m = l + r >> 1;
            if (check(m))
            {
                r = m;
            }
            else
            {
                l = m + 1;
            }
        }
        cout << l << endl;
    }
    return 0;
}</span>
 
 
C. Arithmetic Progression
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Everybody knows what an arithmetic progression is. Let us remind you just in case that an arithmetic progression is such sequence of numbers a1, a2, ..., an of length n, that the following condition fulfills:

a2 - a1 = a3 - a2 = a4 - a3 = ... = ai + 1 - ai = ... = an - an - 1.

For example, sequences [1, 5], [10], [5, 4, 3] are arithmetic progressions and sequences [1, 3, 2], [1, 2, 4] are not.

Alexander has n cards containing integers. Arthur wants to give Alexander exactly one more card with a number so that he could use the resulting n + 1 cards to make an arithmetic progression (Alexander has to use all of his cards).

Arthur has already bought a card but he hasn't written a number on it. Help him, print all integers that you can write on a card so that the described condition fulfilled.

Input

The first line contains integer n (1 ≤ n ≤ 105) — the number of cards. The next line contains the sequence of integers — the numbers on Alexander's cards. The numbers are positive integers, each of them doesn't exceed 108.

Output

If Arthur can write infinitely many distinct integers on the card, print on a single line -1.

Otherwise, print on the first line the number of integers that suit you. In the second line, print the numbers in the increasing order. Note that the numbers in the answer can exceed 108 or even be negative (see test samples).

Sample test(s)
input
3
4 1 7
output
2
-2 10
input
1
10
output
-1
input
4
1 3 5 9
output
1
7
input
4
4 3 4 5
output
0
input
2
2 4
output
3
0 3 6
解题思路

        这道题就是能否向一个数列中加入一个数使得这个数列变成等差数列。然后就需要对n的个数进行分类。我只是对n==1,n==2进行了特殊情况的判断。后来有点晕,忽略了只能最多加入一个数。所以当有多个数满足差值等于2倍的等差数列的差值时,这应该是0。当n>=3时,在数列中间最多只能出现一个这种大的空缺情况。否则都为0。主要是if else的情况判断。不是特别难。

参考代码

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

const int maxn=1000100;
const int INF=(1<<30);

int a[maxn],b[maxn];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        if(n==1)
        {
            printf("-1\n");
            continue;
        }
        sort(a,a+n);
        if(n==2)
        {
            int num=a[1]-a[0];
            if(a[0]==a[1])
                printf("1\n%d\n",a[0]);
            else if((a[1]-a[0])%2==0)
                printf("3\n%d %d %d\n",a[0]-num,a[0]+num/2,a[1]+num);
            else
                printf("2\n%d %d\n",a[0]-num,a[1]+num);
            continue;
        }
        int num=INF;
        for(int i=1; i<n; i++)
            num=min(num,a[i]-a[i-1]);
        bool flag=0;
        for(int i=1; i<n; i++)
            if(a[i]-a[i-1]!=num)
                flag=1;
        if(flag)
        {
            int s=0;
            int flag1=1;
            for(int i=1; i<n; i++)
                if(a[i]-a[i-1]!=num)
                {
                    if(a[i]-a[i-1]!=2*num)
                    {
                        flag1=0;
                        break;
                    }
                    else
                    {
                        if(s>0)
                        {
                            flag1=0;
                            break;
                        }
                        b[s++]=a[i-1]+num;
                    }
                }
            if(flag1)
            {
                printf("%d\n",s);
                for(int i=0;i<s;i++)
                    printf("%d ",b[i]);
                printf("\n");
            }
            else
                printf("0\n");
        }
        else
        {
            if(num==0)
                printf("1\n%d\n",a[0]);
            else
                printf("2\n%d %d\n",a[0]-num,a[n-1]+num);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值