第二周周赛——加油 题解(分别出自HDU5615,HDU5586,codeforces 319B,codeforces 518C,codeforces 548D)

A题:

A题题目链接

题目描述:

QAQ又遇到数学问题了

TimeLimit:1000MS  MemoryLimit:65536KB
64-bit integer IO format: %I64d

Problem Description

Jam有道数学题想向你请教一下,他刚刚学会因式分解比如说,x^2+6x+5=(x+1)(x+5)就好像形如 ax^2+bx+c => pqx^2+(qk+mp)x+km=(px+k)(qx+m)但是他很蠢,他只会做p,q,m,k为正整数的题目 请你帮助他,问可不可以分解

Input

第一行T,表示T(1≤T≤100)组数据。

接下来T组数据:

每组数据一行,一个三个整数a,b,c,一组数据一行(1≤a,b,c≤100000000)

Output

对于每组数据,输出"YES"或者"NO".

SampleInput
2
1 6 5
1 6 4
SampleOutput
YES
NO
提示:
第一组数据可以分成(x+1)(x+5)=x^2+6*x+5
解析:

由于这道题的数据比较弱,所以暴力遍历还是能够过的,但是我们需要掌握的是能够在多数情况下均可行的方法。

我们首先来观察一下这个一元二次多项式

ax^2 + b*x + c

要使这个一元二次多项式能够化成pqx^2+(qk+mp)x+km=(px+k)(qx+m)的形式,我们很容易就联想到了高中老师教过的十字相乘解方程组的做法。

所以首先我们对这个方程式进行求解,令Δ = b^2 - 4*a*c,那么我们根据韦达定理,可以求得

x1 = (-b + sqrt(Δ) ) / 2*a,x2 =  (-b - sqrt(Δ) ) / 2*a;

由于a值是大于0的,那么我们可以等式两边同时乘以2a,即得

2*a*x1 = (-b + sqrt(Δ) ),2*a*x2 = (-b - sqrt(Δ) );

那么在题目中我们需要的得到的是形如(px+k)(qx+m) = 0的等式,那么根据我们上述求解到的等式,则可以将其右边的等式分别移至左边,两者再相乘,得

(2*a*x1 + b - sqrt(Δ)) * (2*a*x1 + b + sqrt(Δ)) = 0;

而由于Δ = b^2 - 4*a*c,并且a,b,c均大于0.

那么b - sqrt(Δ)大于0是恒成立的,所以呢,要得到形如(px+k)(qx+m) = 0的等式(p,k,q,m均为正整数),那么我们sqrt(Δ)必须要是整数

要使sqrt(Δ)为整数,那么Δ必须要是完全平方数才能满足条件(完全平方数:若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。完全平方数是非负数。而一个完全平方数的项有两个。

所以我们推算到这里,就发现原来的问题转换为求Δ = b^2 - 4*a*c是否为完全平方数即可,是则输出YES,不是则输出NO。

完整代码实现:

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
int main(){
    int T;
    ll a,b,c;
    scanf("%d",&T);
    while(T--){
        scanf("%I64d %I64d %I64d",&a,&b,&c);
        ll tmp = b*b-4*a*c;
        if((ll)(sqrt(tmp)+0.5) * (ll)(sqrt(tmp)+0.5) != tmp){
            printf("NO\n");
        }
        else{
            printf("YES\n");
        }
    }
    return 0;
}

关于浮点数精度问题的描述注意浮点数带来的安全隐患,隐藏的BUG):

似是而非的k=sqrt(n)

B题:

B题题目链接

题目描述:

和和和和和

TimeLimit:1000MS  MemoryLimit:65536KB
64-bit integer IO format: %I64d

Problem Description

给n个数A1,A2....An,你可以选择一个区间(也可以不选),区间里每个数x变成f(x),其中f(x)=(1890x+143)mod10007。问最后n个数之和最大可能为多少。

Input

输入有多组数据。
每组数据第一行包含一个整数n.(1≤n≤105)
第二行n个整数A1,A2....An.(0≤Ai≤104)
数据保证∑n ≤106

Output

对于每组数据输出一行答案.

SampleInput
2
10000 9999
5
1 9999 1 9999 1
SampleOutput
19999
22033

解析:

这道题乍一看会觉得比较难而没头绪,但是我们可以从题目入手,题目是要将若干个x替换成f(x),也可以保持原样不替换,然后问操作过后这剩下的n个数的和最大会是多少?那么我们就要思考一个问题,在什么情况下,我们需要将x替换成f(x)呢?很明显,根据题目的需求入手,要使这剩下的n个数的和最大,那么当f(x)的值大于x时,替换才是有价值的。否则的话,x则保持原样,而如果要进行替换的话,根据题目要求,我们必须要选定一个区间进行替换。所以我们可以作以下总结:

对于Xi(1<=i<=n),当f(Xi)> Xi时,即f(Xi)- Xi > 0时,我们则可以将Xi替换成f(Xi)

所以呢,我们可以另外用一个数组记录每个f(X)- X的值,并且在输入的过程中用ans记录n个x的总和,例如我们得到了以下的数组:

1 -3 4 3 -5 2

那么很明显,对于以上数组,我们选择的区间为[3,4]时(即将第3个数和第4个数替换成f(X)),能够使得最后的n个数的和最大。

那么我们从上面的分析可以知道,只要找到f(X)- X差值数组中最大的子序列,如果这个最大的子序列大于0,那么这个子序列中的x替换成f(x),可以使得最后的结果最大。

一开始的时候,我们可以设置两个变量,分别存储当前最大的子序列的值以及当前扫描到的子序列的和:

int max_num = 0,this_num = 0; //初始值均设置为0,当max_num的值大于0时,才对最后n个数的总和有影响

那么我们从头开始扫描,每扫描到一个数,我们将其加至this_num上,表示当前扫描到的子序列的和,如果this_num的值大于max_num,那么我们则要更新当前最大子序列的值,而如果this_num在扫描过程中遇到负数的话,那么this_num的值将会减小,直到this_num小于0,这时我们就可以抛弃前面已经扫描过的子序列,将this_num置为0,从当前位置继续扫描下去。期间再不断更新当前最大子序列的值,直到所有的数都扫描完毕。

你肯定会问,问什么当this_num小于0,我们就可以抛弃前面已经扫描过的子序列呢?原因很简单,我们要的是和大于0的子序列,这样的话才会对最后输出的结果产生影响,而这时前面已经扫描过的子序列的总和小于0,说明这些子序列"拖累"了最大的子序列。(举个简单的例子:比如说前面k个数的和为-2,后面还有三个数,分别是1,3,4,那么最大子序列的值显而易见是1+3+4 = 8,而如果你没有抛弃前面k个数,而是继续叠加下去,那么得出的最大子序列值将会是6,这样的话使得实际的值减小了,很明显,如果我们抛弃掉累赘才能获得更大的值)

当扫描完毕之后,我们将ans+max_num即可(如果扫描期间有子序列的值大于max_num的初始值0,则最后的结果是ans+max_num,否则max_num的值始终没有得到更新,所以呢,最后的结果是ans,表示一个x都不替换,而此时max_num的值为0,对结果是无影响的,所以最后输出ans+max_num),完整代码实现:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = (int)1e5 + 10;
int num[maxn],f[maxn];
int main(){
    int n;
    while(scanf("%d",&n)==1&&n){
        int ans = 0;
        for(int i = 1;i <= n;i++){
            scanf("%d",&num[i]);
            f[i] = (num[i] * 1890 + 143) % 10007 - num[i];      //用于存储每个A[i]与num[i]的差值
            ans += num[i];
        }
        int max_num = 0,this_num = 0;
        for(int i = 1;i <= n;i++){
            this_num += f[i];
            if(this_num > max_num){
                max_num = this_num;
            }
            else if(this_num<0){
                this_num = 0;
            }
        }
        printf("%d\n",max_num+ans);
    }
    return 0;
}

其实这个问题是典型的动态规划入门题,最大子序列和,我找了几篇比较好的文章分享给大家:

六种姿势拿下连续子序列最大和问题,附伪代码(以HDU 1003 1231为例)

动态规划经典题目:最大连续子序列和

C题:

C题题目链接

题目描述:

Psychos in a Line

TimeLimit:1000MS  MemoryLimit:256MB
64-bit integer IO format: %I64d

Problem Description

There are n psychos standing in a line. Each psycho is assigned a unique integer from 1 to n. At each step every psycho who has an id greater than the psycho to his right (if exists) kills his right neighbor in the line. Note that a psycho might kill and get killed at the same step.

You're given the initial arrangement of the psychos in the line. Calculate how many steps are needed to the moment of time such, that nobody kills his neighbor after that moment. Look notes to understand the statement more precise.

Input

The first line of input contains integer n denoting the number of psychos, (1 ≤ n ≤ 105). In the second line there will be a list of n space separated distinct integers each in range 1 to n, inclusive — ids of the psychos in the line from left to right.

Output

Print the number of steps, so that the line remains the same afterward.

SampleInput 1
10
10 9 7 8 6 5 3 4 2 1
SampleOutput 1
2
SampleInput 2
6
1 2 3 4 5 6
SampleOutput 2
0
   
   
Note

In the first sample line of the psychos transforms as follows: [10 9 7 8 6 5 3 4 2 1]  →  [10 8 4]  →  [10]. So, there are two steps.

解法实例:

Psychos in a Line【栈】

D题:

题目链接

Mike and Feet

TimeLimit:1000MS  MemoryLimit:256MB
64-bit integer IO format: %I64d

Problem Description

Mike is the president of country What-The-Fatherland. There are n bears living in this country besides Mike. All of them are standing in a line and they are numbered from 1 to n from left to right. i-th bear is exactly ai feet high.

A group of bears is a non-empty contiguous segment of the line. The size of a group is the number of bears in that group. The strength of a group is the minimum height of the bear in that group.

Mike is a curious to know for each x such that 1 ≤ x ≤ n the maximum strength among all groups of size x.

Input

The first line of input contains integer n (1 ≤ n ≤ 2 × 105), the number of bears.

The second line contains n integers separated by space, a1, a2, ..., an (1 ≤ ai ≤ 109), heights of bears.

Output

Print n integers in one line. For each x from 1 to n, print the maximum strength among all groups of size x.

SampleInput
10
1 2 3 4 5 4 3 2 1 6
SampleOutput
6 4 4 3 3 2 2 1 1 1 
解法示例:

Codeforces548D:Mike and Feet(单调栈)

Codeforces 548D Mike and Feet (单调栈)

E题:

E题题目链接

题目描述:

Anya and Smartphone

TimeLimit:1000MS  MemoryLimit:256MB
64-bit integer IO format: %I64d

Problem Description

Anya has bought a new smartphone that uses Berdroid operating system. The smartphone menu has exactly napplications, each application has its own icon. The icons are located on different screens, one screen contains k icons. The icons from the first to the k-th one are located on the first screen, from the (k + 1)-th to the 2k-th ones are on the second screen and so on (the last screen may be partially empty).

Initially the smartphone menu is showing the screen number 1. To launch the application with the icon located on the screen t, Anya needs to make the following gestures: first she scrolls to the required screen number t, by making t - 1gestures (if the icon is on the screen t), and then make another gesture — press the icon of the required application exactly once to launch it.

After the application is launched, the menu returns to the first screen. That is, to launch the next application you need to scroll through the menu again starting from the screen number 1.

All applications are numbered from 1 to n. We know a certain order in which the icons of the applications are located in the menu at the beginning, but it changes as long as you use the operating system. Berdroid is intelligent system, so it changes the order of the icons by moving the more frequently used icons to the beginning of the list. Formally, right after an application is launched, Berdroid swaps the application icon and the icon of a preceding application (that is, the icon of an application on the position that is smaller by one in the order of menu). The preceding icon may possibly be located on the adjacent screen. The only exception is when the icon of the launched application already occupies the first place, in this case the icon arrangement doesn't change.

Anya has planned the order in which she will launch applications. How many gestures should Anya make to launch the applications in the planned order?

Note that one application may be launched multiple times.

Input

The first line of the input contains three numbers n, m, k (1 ≤ n, m, k ≤ 105) — the number of applications that Anya has on her smartphone, the number of applications that will be launched and the number of icons that are located on the same screen.

The next line contains n integers, permutation a1, a2, ..., an — the initial order of icons from left to right in the menu (from the first to the last one), ai —  is the id of the application, whose icon goes i-th in the menu. Each integer from 1 to n occurs exactly once among ai.

The third line contains m integers b1, b2, ..., bm(1 ≤ bi ≤ n) — the ids of the launched applications in the planned order. One application may be launched multiple times.

Output

Print a single number — the number of gestures that Anya needs to make to launch all the applications in the desired order.

SampleInput 1
8 3 3
1 2 3 4 5 6 7 8
7 8 1
SampleOutput 1
7
SampleInput 2
5 4 2
3 1 5 2 4
4 4 4 4
SampleOutput 2
8
   
   
Note

In the first test the initial configuration looks like (123)(456)(78), that is, the first screen contains icons of applications 1, 2, 3, the second screen contains icons 4, 5, 6, the third screen contains icons 7, 8.

After application 7 is launched, we get the new arrangement of the icons — (123)(457)(68). To launch it Anya makes 3 gestures.

After application 8 is launched, we get configuration (123)(457)(86). To launch it Anya makes 3 gestures.

After application 1 is launched, the arrangement of icons in the menu doesn't change. To launch it Anya makes 1 gesture.

In total, Anya makes 7 gestures.

题解示例:

Anya and Smartphone

官方题解(英文)


如有错误,还请指正,O(∩_∩)O谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值