Contest2785 - 2021个人训练赛第7场GH

Given is a positive integer N, where none of the digits is 0.Let k be the number of digits in N. We want to make a multiple of 3 by erasing at least 0 and at most k−1 digits from N and concatenating the remaining digits without changing the order.
Determine whether it is possible to make a multiple of 3 in this way. If it is possible, find the minimum number of digits that must be erased to make such a number.

Constraints
1≤N<1018
None of the digits in N is 0.

输入
Input is given from Standard Input in the following format:

N
输出
If it is impossible to make a multiple of 3, print -1; otherwise, print the minimum number of digits that must be erased to make such a number.

样例输入 Copy
【样例1】
35
【样例2】
369
【样例3】
6227384
【样例4】
11
样例输出 Copy
【样例1】
1
【样例2】
0
【样例3】
1
【样例4】
-1
提示
样例1解释:By erasing the 5, we get the number 3, which is a multiple of 3. Here we erased the minimum possible number of digits - 1.
样例2解释:Note that we can choose to erase no digit.
样例3解释:For example, by erasing the 8, we get the number 622734, which is a multiple of 3.
样例4解释:Note that we must erase at least 0 and at most k−1 digits, where k is the number of digits in N, so we cannot erase all the digits.
In this case, it is impossible to make a multiple of 3 in the way described in the problem statement, so we should print -1.
这个题本质我用的dfs 写的不咋地
用dfs干嘛呢
题目给一个长度为k的数字
我用dfs找k-1位 到1位的数
如果找到 直接停止

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double llf;
const int maxn=1e6+199;
inline int read(){  char ch = getchar();int x = 0,f = 1;while(ch < '0' || ch > '9')
{if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9'){  x = x * 10 + ch - '0';  ch = getchar(); }return x * f;}
ll a[10007];
//ll cnt=0;
map<int,int>mp;
vector<int>p;
int nex[maxn];
 

int cnt=0,flag=0;
void dfs(ll n,int tot,int k,int w,int h){
    if(tot==k&&!flag){
        //cout<<n<<endl;
        if(n%3==0&&h==k){
            cout<<cnt-k;
             
            flag=1;
        }
        return;
    }
    if(flag)
    return;
    for(int i=w;i<=cnt;i++){
        dfs(n*10+a[i],tot+1,k,i+1,h+1);
        dfs(n,tot+1,k,i+1,h);
    }
}
int main(){
    ll n,m;
    scanf("%lld",&n);
    if(n%3==0){
        cout<<0;
        return 0;
    }
    m=n;
    while(m){
        a[++cnt]=m%10;
        m/=10;
    }
    for(int i=1;i<=cnt/2;i++){
        swap(a[i],a[cnt-i+1]);
    }
     
    for(int j=cnt-1;j>=1;j--){
        for(int k=1;k<=cnt-j+1;k++){
        dfs(a[k],1,j,k+1,1);
        }
    }
    if(!flag)
    cout<<-1;
    return 0;  
} 

问题 H: Wandering
时间限制: 1 Sec 内存限制: 128 MB

题目描述
Given is a number sequence A1,A2,A3,…,AN, which may contain negative elements.
On a number line, there is a robot at coordinate 0. It will do the following actions in order:
Move A1 in the positive direction.
Move A1 in the positive direction, and then move A2 in the positive direction.
Move A1 in the positive direction, then move A2 in the positive direction, and then move A3 in the positive direction.

Move A1 in the positive direction, then move A2 in the positive direction, then move A3 in the positive direction, …, …, and then move AN in the positive direction.
Find the greatest coordinate occupied by the robot from the beginning to the end of the process.

Constraints
1≤N≤200000
−108≤Ai≤108
All values in input are integers.
输入
Input is given from Standard Input in the following format:

N
A1 A2 A3…AN
输出
Print the greatest coordinate occupied by the robot from the beginning to the end of the process.
样例输入 Copy
【样例1】
3
2 -1 -2
【样例2】
5
-2 1 3 -1 -1
【样例3】
5
-1000 -1000 -1000 -1000 -1000
样例输出 Copy
【样例1】
5
【样例2】
2
【样例3】
0
提示
样例1解释:
The robot moves as follows:
Move 2 in the positive direction, to coordinate 2.
Move 2 in the positive direction, to coordinate 4. Then move −1 in the positive direction, to coordinate 3.
Move 2 in the positive direction, to coordinate 5. Then move −1 in the positive direction, to coordinate 4.
Then move −2 in the positive direction, to coordinate 2.
The greatest coordinate occupied during the process is 5, so we should print 5.
样例3解释:
In this case, the initial coordinate 0 is the greatest coordinate occupied.
这个题我自认为是dp
如果一遍遍模拟的话 我估摸着会t
我们用dp来模拟前缀和
用pp来记录当前下标下 最大前缀和
所以在每一次执行的时候 我们可以直接进行pp的运算得到最大值
然后就可以跳过 o(n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double llf;
const int maxn=1e6+199;
inline int read(){	char ch = getchar();int x = 0,f = 1;while(ch < '0' || ch > '9')
{if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9'){	x = x * 10 + ch - '0';	ch = getchar();	}return x * f;}
ll a[maxn];
//ll cnt=0;
ll pp[maxn];
ll dp[maxn];
int main(){
	ll n,m;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		cin>>a[i];
		dp[i]=dp[i-1]+a[i];
	}
	ll x=0;
	ll cnt=0;
	for(int i=1;i<=n;i++){
		pp[i]=max(pp[i-1],dp[i]);
	//	cout<<pp[i]<<endl;
	}
	for(int i=1;i<=n;i++){
		
		x+=pp[i];
		cnt=max(cnt,x);
		x-=pp[i];
		x+=dp[i];
	}
	cout<<cnt;
    return 0;  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛郎恋刘娘,刘娘念牛郎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值