[codeforces] #608 div2 部分题解

A题:

签到。

public class Main {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader sc = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, sc, out);
        out.close();
    }

    static class Task {
        public void solve(int testNumber, InputReader sc, PrintWriter out) throws IOException {
        	long a=sc.nextLong();
        	long b=sc.nextLong();
        	long c=sc.nextLong();
        	long d=sc.nextLong();
        	long e=sc.nextLong();
        	long f=sc.nextLong();
        	b=Math.min(b, c);
        	if(e>f) {
        		long ans=Math.min(a, d)*e;
        		ans+=Math.min(b, d-Math.min(a, d))*f;
        		out.println(ans);
        	}
        	else {
        		long ans=Math.min(b, d)*f;
        		ans+=Math.min(a, d-Math.min(b, d))*e;
        		out.println(ans);
        	}
        }

    }

    static class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
        
        public double nextDouble() throws NumberFormatException, IOException {
        	return Double.parseDouble(next());
        }
        
        public BigInteger nextBigInteger() throws IOException {
        	return new BigInteger(next());
        }
    }
}

B题:

思维,首先不要求是最优解,并且翻转次数小于等于3*n次。那么我们可以从第二个开始,只要和前面的不同就翻转,如果到了最后一个块和前面的颜色不同,就判断前面块的总数是否为偶数即可。

public class Main {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader sc = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, sc, out);
        out.close();
    }

    static class Task {
        public void solve(int testNumber, InputReader sc, PrintWriter out) throws IOException {
        	int n=sc.nextInt();
        	String t=sc.next();
        	int[] s=new int[t.length()];
        	int ans=0;
        	ArrayList<Integer> buf=new ArrayList<>();
        	for(int i=0;i<t.length();i++)
        		s[i]=(t.charAt(i)=='W')?1:0;
        	for(int i=1;i<s.length;i++) {
        		if(s[i]!=s[i-1]) {
        			if(i+1>=s.length) {
        				break;
        			}
        			ans++;
        			buf.add(i);
        			s[i]^=1;
        			s[i+1]^=1;
        		}
        	}
        	if(s[s.length-1]==s[s.length-2]) {
        		out.println(ans);
        		for(int v:buf)
        			out.print((v+1)+" ");
        		return ;
        	}
        	if(s.length%2==0) {
        		out.println("-1");
        		return ;
        	}
        	ans+=s.length/2;
        	out.println(ans);
        	for(int v:buf)
    			out.print((v+1)+" ");
        	for(int i=0;i+1<t.length();i+=2) 
        		out.print((i+1)+" ");
        	
        }

    }

    static class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
        
        public double nextDouble() throws NumberFormatException, IOException {
        	return Double.parseDouble(next());
        }
        
        public BigInteger nextBigInteger() throws IOException {
        	return new BigInteger(next());
        }
    }
}

C题:

思维,将点分成8类,与(sx,sy)单个坐标相同的四种情况,以及(sx,sy)左上、右上、左下、右下四种,然后分类讨论排序即可。

public class Main {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader sc = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, sc, out);
        out.close();
    }

    static class Task {
        public void solve(int testNumber, InputReader sc, PrintWriter out) throws IOException {
        	int[] x=new int[2];   //0 up 1down
        	int[] y=new int[2]; 	//0 left 1 right
        	int[] cnt=new int[4];
        	int n=sc.nextInt();
        	int sx=sc.nextInt();
        	int sy=sc.nextInt();
        	for(int i=0;i<n;i++) {
        		int ax=sc.nextInt();
        		int ay=sc.nextInt();
        		if(ax==sx) {
        			if(ay>sy)
        				x[0]++;
        			else
        				x[1]++;
        			continue;
        		}
        		if(ay==sy) {
        			if(ax<sx)
        				y[0]++;
        			else
        				y[1]++;
        			continue;
        		}
        		if(ax<sx&&ay>sy)
        			cnt[0]++;
        		if(ax>sx&&ay>sy)
        			cnt[1]++;
        		if(ax>sx&&ay<sy)
        			cnt[2]++;
        		if(ax<sx&&ay<sy)
        			cnt[3]++;
        	}
        	ArrayList<Node> buf=new ArrayList<>();
        	buf.add(new Node(cnt[0]+cnt[1]+x[0],sx,sy+1));
        	buf.add(new Node(cnt[2]+cnt[3]+x[1],sx,sy-1));
        	buf.add(new Node(cnt[0]+cnt[3]+y[0],sx-1,sy));
        	buf.add(new Node(cnt[1]+cnt[2]+y[1],sx+1,sy));
        	Collections.sort(buf);
        	out.println(buf.get(0).val);
        	out.println(buf.get(0).x+" "+buf.get(0).y);
        }

    }
    
    static class Node implements Comparable<Node>{
    	int val;
    	int x;
    	int y;
    	
    	public Node(int val,int x,int y) {
    		this.val=val;
    		this.x=x;
    		this.y=y;
    	}

		@Override
		public int compareTo(Node o) {
			return o.val-this.val;
		}
    }

    static class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
        
        public double nextDouble() throws NumberFormatException, IOException {
        	return Double.parseDouble(next());
        }
        
        public BigInteger nextBigInteger() throws IOException {
        	return new BigInteger(next());
        }
    }
}

E题:

数学+证明+二分。

可以观察到在同一路径上的所有数都在二进制表示中都有相同的前缀,并且这是很容易证明的(此处略过),如果注意到这个性质,那么我们就可以对x分奇偶进行二分(如果不分奇偶显然不具有单调性)。此题细节比较多(可能我写疵了),写起来比较麻烦。

public class Main {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader sc = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, sc, out);
        out.close();
    }

    static class Task {
    	public boolean check(long x,long n,long k) {
    		if(x%2==1) {
    			long a=x;
    			long ans=1;
    			String temp=Long.toBinaryString(x);
    			int len=Long.toBinaryString(n).length();
    			for(int i=temp.length()+1;i<len;i++) {
    				ans+=1l<<(i-temp.length());
    			}
    			if(len-temp.length()>=0) {
    				x<<=(len-temp.length());
        			if(x<=n) {
        				ans+=Math.min(1l<<(len-temp.length()), n-x+1);
        				if(Long.toBinaryString(a).length()==len)
            				ans--;
        			}
    			}
    			return ans>=k;
    		}
    		else {
    			long a=x;
    			long ans=1;
    			long y=x+1;
    			if(y<=n)
    				ans++;
    			String temp=Long.toBinaryString(y);
    			int len=Long.toBinaryString(n).length();
    			for(int i=temp.length()+1;i<len;i++)
    				ans+=1l<<(i-temp.length());
    			boolean flag=false;
    			if(temp.length()<=len) {
    				y<<=(len-temp.length());
        			if(y<=n){
        				ans+=Math.min(1l<<(len-temp.length()), n-y+1);
        				if(Math.min(1l<<(len-temp.length()), n-y+1)==n-y+1)    //n只加一次
        					flag=true;
        				if(Long.toBinaryString(a).length()==len)  //相等时开头加过一次
            				ans--;
        			}
        			
        			
    			}
    			temp=Long.toBinaryString(x);
    			for(int i=temp.length()+1;i<len;i++)
    				ans+=1l<<(i-temp.length());
    			if(temp.length()<=len) {
    				x<<=(len-temp.length());
        			if(x<=n) {
        				if(!flag)
            				ans+=Math.min(1l<<(len-temp.length()), n-x+1);
        				else

            				ans+=Math.min(1l<<(len-temp.length()), n-x);
        			}
        			if(Long.toBinaryString(a).length()==len)      //相等时开头加过一次
        				ans--;
    			}
    			return ans>=k;
    		}
    	}
    	
        public void solve(int testNumber, InputReader sc, PrintWriter out) throws IOException {
        	long n=sc.nextLong();
        	long k=sc.nextLong();
        	
        	long l=0;
        	long r=(n%2==0)?n/2-1:n/2;
        	long ans=1;
        	while(l<=r) {
        		long mid=(l+r)>>1;
        		long x=mid*2+1;
        		if(check(x,n,k)) {
        			ans=x;
        			l=mid+1;
        		}
        		else
        			r=mid-1;
        	}
        	l=0;
        	r=n/2;
        	while(l<=r) {
        		long mid=(l+r)>>1;
        		long x=mid*2;
        		if(check(x,n,k)) {
        			ans=Math.max(ans, x);
        			l=mid+1;
        		}
        		else
        			r=mid-1;
        	}
        	out.println(ans);
        }
    }

    static class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
        
        public double nextDouble() throws NumberFormatException, IOException {
        	return Double.parseDouble(next());
        }
        
        public BigInteger nextBigInteger() throws IOException {
        	return new BigInteger(next());
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值