Codeforces Round #555 (Div. 3) Editorial

蛋疼用java打CF,要把包package去掉,否则会RE

A. Reachable Numbers 1300

题意:

定义一个函数F, F(x)=x+1,然后把x+1的后置0都去掉

输入一个n,问F(n)的无限次迭代能访问到的数目

思路:开个hashmap跑记忆化dfs即可

import java.util.*;
import java.math.*;
public class Animal {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		Fun fun=new Fun();
		fun.dfs(n);
		System.out.println(fun.h1.size());
	}
	static class Fun{
		public HashMap<Integer, Integer>h1=new HashMap<Integer, Integer>();
		public void dfs(int x){
			if(h1.containsKey(x))return ;
			h1.put(x, 1);
			x=x+1;
			while(x%10==0)x/=10;
			dfs(x);
		}
	}
	
}

B. Long Number 1300

题意:给出一些数字的替换函数F,比如F(1)=2代表可以把1替换成2

现在输入一个长度为n的数字串s,选择s其中的一个连续子串,

使用1或0次该规则,使得数字串最大

坑点:java字符串用stringbuilder连接会快,用string +=很慢

思路:找到第一个替换比原来大的连续子串即可,注意=也可以继续找

import java.util.*;
import java.math.*;
public class Animal {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int f[]=new int [10];
		int n=scanner.nextInt();
		char []s=scanner.next().toCharArray();
		
		String ans=new String();
		for(int i=1;i<=9;i++)
			f[i]=scanner.nextInt();
		
		int i=0;
		while(i<n&&f[s[i]-'0']<=s[i]-'0')//
			i++;
		while(i<n&&f[s[i]-'0']>=s[i]-'0')
		{
			s[i]=(char)(f[s[i]-'0']+'0');i++;
		}
			
		
		//System.out.println(s);
		System.out.println(new String(s));
		  
	}
	public static class Fun{
		public HashMap<Integer, Integer>h1=new HashMap<Integer, Integer>();
		
		public void dfs(int x[]){
			x[0]=x[0]+5;
		}
	}
	
}

C1. Increasing Subsequence (easy version) 1700

题意:给出一个互不相等的数组a,现在从a的两端取出数字,

规则是取出的数字要一个比一个大,问能最多能取出多少数字?

思路:双指针,贪心尽量取小,学到了一个减少if else的骚操作

import java.util.*;
import java.math.*;
public class Animal {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		int a[]=new int[n+5];
		for(int i=1;i<=n;i++)
			a[i]=scanner.nextInt();
		int l=1;int r=n;
		int mx=0;int sz=0;
		char ans[]=new char[n];
	
		while(true){
			if(l>r)break;
			if(a[l]<mx&&a[r]<mx)break;
			if(a[r]<mx||mx<a[l]&&a[l]<a[r]){
				ans[sz++]='L';mx=a[l];l++;
			}
			else{
				ans[sz++]='R';mx=a[r];r--;
			}
		}
		System.out.println(sz);
		for(int i=0;i<sz;i++)
			System.out.print(ans[i]);
	}
	public static class Fun{
		public HashMap<Integer, Integer>h1=new HashMap<Integer, Integer>();
		
		public void dfs(int x[]){
			x[0]=x[0]+5;
		}
	}
}

困难版C2:1700

题意:数组有可能相等

思路:对于a[l]=a[r]的部分,从l往r跑一遍,r往l跑一遍,看谁跑得数字多就好

记得更新当前的最大值mx

import java.util.*;
import java.math.*;
public class Animal {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		int a[]=new int[n+5];
		for(int i=1;i<=n;i++)
			a[i]=scanner.nextInt();
		int l=1;int r=n;
		int mx=0;int sz=0;
		char ans[]=new char[n];
	
		while(l<=r&&(a[r]>mx||a[l]>mx)){
			//System.out.println(l+"??"+r+"??"+mx);
			
			
			if(a[r]<=mx||(mx<a[l]&&a[l]<a[r]) ){
				ans[sz++]='L';mx=a[l];l++;
			}
			else if(a[l]<=mx||(mx<a[r]&&a[r]<a[l])) {
				ans[sz++]='R';mx=a[r];r--;
			}
			else {//a[l]==a[r]
				int gol=0;
				int gor=0;
				int tm=mx;
				for(int t=l;t<r;t++){
					if(a[t]<=mx)break;
					mx=a[t];gol++;
				}
				mx=tm;
				for(int t=r;t>l;t--){
					if(a[t]<=mx)break;
					mx=a[t];gor++;
				}
				//System.out.println(gol+"dd"+gor+"dd"+mx);
				if(gol>gor){
					l+=gol-1;
					for(int i=1;i<=gol;i++)
						ans[sz++]='L';
					mx=a[l];
				}else{
					r-=gor-1;
					for(int i=1;i<=gor;i++)
						ans[sz++]='R';
				}
			}
			
		}
		System.out.println(sz);
		for(int i=0;i<sz;i++)
			System.out.print(ans[i]);
	}
	public static class Fun{
		public HashMap<Integer, Integer>h1=new HashMap<Integer, Integer>();
		
		public void dfs(int x[]){
			x[0]=x[0]+5;
		}
	}
}

D. N Problems During K Days 2100

题意:构造一个数列,和为n

限制:数列递增,数列相邻值相差不超过前一项的两倍

思路:

 从x开始连续相差1的i(1<=i<=k)个数 之和sum

让sum尽量接近n,然后n-=x,x留下,在剩下的数字里重复跑这个

i倒叙遍历,最后判断n是否为0即可

import java.util.*;
import java.math.*;
public class Animal {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		long n=scanner.nextInt();
		long k=scanner.nextInt();
		int a[]=new int [(int)(k+5)];long pre=0;long x;int fl=0;
		for(long i=k;i>=1;i--)
		{
			x=(2*n/i-i+1)/2;
			x=Math.max(x, pre+1);
			if(fl==1)
			{
				x=Math.min(x, 2*pre);
			}
			pre=x;fl=1;
			
			a[(int)(k-i+1)]=(int)x;
			//System.out.println(k+":"+x+":"+n);
			n-=x;
		}
		if(n!=0){
			System.out.println("NO");
		}else{
			System.out.print("YES"+"\n"+a[1]);
			for(int i=2;i<=k;i++)
				System.out.print(" "+a[i]);
		}
	}
	public static class Fun{
		public HashMap<Integer, Integer>h1=new HashMap<Integer, Integer>();
		
		public long sum(long a1,long k){
			return (a1+a1+k-1)*k/2;
		}
	}
}

E - Minimum Array 1700

题意:给出俩数组a b   0<=ai,bi<n

重序b使得ci=(ai+bi)%n 的字典序最小 

思路:multiset+三次二分

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a[200005];
int b[200005];
int ans[200005];
multiset<int>s;
int main()
{
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    for(int i=1;i<=n;i++)s.insert(b[i]);
    
    for(int i=1;i<=n;i++){
        int x=n-a[i];
        multiset<int>::iterator poi=s.lower_bound(x);
        if(poi!=s.end()&&(*poi)==x){
            s.erase(poi);
            ans[i]=0;
        }
        else{
            poi=s.upper_bound(x);
            if(poi!=s.end()){
                ans[i]=(a[i]+(*poi))%n;
                s.erase(poi);
            }
            else{
                poi=s.lower_bound(0);
                ans[i]=(a[i]+(*poi))%n;
                s.erase(poi);
            }
        
        }
    }for(int i=1;i<=n;i++)printf("%d ",ans[i]);puts("");
}

F.Maximum Balanced Circle 2300

想的思路跟题解一致,没时间写了

思路:维护出现次数 ,每个圈由1XXXXX1 形成,x>=2  看那个圈大就好了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值