CodeTON Round 5 (Div. 1 + Div. 2, Rated, Prizes!)前三题复盘

今天来复盘这场div1+div2的比赛,我本人才疏学浅,只a了三个所以就只写了三个

第一题A. Tenzing and Tsondu

很明显这是一道博弈论的题目,细心一点就会发现,它其实胜负就只和选手A和B手中的怪物的血量总数有关,所以将输入便利一遍,谁的更大就输出谁,否则就输出Draw

下面是代码

import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args)throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String s1=reader.readLine();
        int t=Integer.parseInt(s1);
        while(t-->0){
            String s2[]=reader.readLine().split(" ");
            int n1=Integer.parseInt(s2[0]);
            int n2=Integer.parseInt(s2[1]);
            long all1=0l,all2=0l;//all1为前一个选手的怪兽的血量和,all2同理
            String s3[]=reader.readLine().split(" ");
            String s4[]=reader.readLine().split(" ");
            for(int i=0;iall2)System.out.println("Tsondu");
            else if(all1

第二题B. Tenzing and Books

考察的是二进制和贪心运算

先将目标值的二进制搞出来,接着对三行书本依次进行便利,当前数字的每一二进制位都和目标值的二进制进行比如果可行,就将这个数字和预设好的数字进行运算。但对如果目标值的某一位是0,而当前数字的当前位上是1,则说明这个数字不可以进行或运算。如果这个数字不行,由题可知,这一行后面的数字都不进行考虑,直接break出去即可。

最后会发现 预设的数字如果和目标值相同则输出yes负责则no

import java.util.*;
import java.io.*;
public class Main {
    public static void main(String[] args)throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String s1=reader.readLine();
        int t=Integer.parseInt(s1);
        while(t-->0){
            String s2[]=reader.readLine().split(" ");
            int n1=Integer.parseInt(s2[0]);
            int x=Integer.parseInt(s2[1]);
            int a[]=new int[32]; //存放的是x的二进制码
            int end=0;
            for(int i=0;i<32;i++){
                if(((x>>i)&1)==1){
                    a[i]=1;
                }
            }
            int k=0;
            if(x==0)k=1;
            int b[]=new int[32];
            int count=0;
            for(int i=0;i<32;i++){
                if(a[i]==b[i])count++;
            }
            
            int t1=3;
            while(t1-->0){
                String s3[]=reader.readLine().split(" ");
                for(int i=0;i>i)&1)==0&&((d>>i)&1)==1){
                return false;
            }
        }
        return true;
    }
}
#include
using namespace std;
const int N = 1e4+10;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        long long n , x , res = 0;
        cin>>n>>x;
        for(int i = 0;i < 3;i++)
        {
            int l = 1;
            for(int j = 0;j < n;j++)
            {
                int t;
                cin>>t;
            if((t|x) == x&&l == 1) res |= t;
        else l = 0;
        }
    }
    if(res == x) cout<<"Yes"<

第三题C. Tenzing and Balls

这个题如果暴力的话,不仅很难写而且绝对会爆空间

最优的解就是动态规划

每一个dp[i]都表示当只有前i个数时的最优解

接下来就考虑状态转移,

1.首先如果dp[i-1]大于dp[i],那么就更新dp[i];

2.该位置的数字与它第一次出现的位置可能会出现最大值,那么dp【i]=第一次出现的位置的前一个dp加i-第一次出现的位置+1;

3该位置的数字与它前一次出现的位置进行删除会产生新的最大值,那么dp【i】=上一次出现的位置的前一个dp加i-j+1;

4.该位置的数字与它前一次出现的进行合并(要求当前一个位置不是第一次出现的位置)dp【i】=上一次出现的位置的dp值加 I-上一次出现的位置

详情见代码注释

import java.util.*;
import java.io.*;
public class Main {
    public static void main(String[] args)throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String s1=reader.readLine();
        int t=Integer.parseInt(s1);
        while(t-->0){
            Map map=new HashMap();//记录每个数字第一次出现的位置
            Map map1=new HashMap();//记录每个数字第二次出现的位置
            String s2=reader.readLine();
            int n=Integer.parseInt(s2);
            String s3[]=reader.readLine().split(" ");
            int dp[]=new int[n+1];//状态转移数组
            for(int i=1;i<=n;i++){
                int e=Integer.parseInt(s3[i-1]);
                if(!map.containsKey(e)){
                    map.put(e, i);//如果没有记录过就添加进去
                    map1.put(e, i);//同理添加
                    dp[i]=dp[i-1];
                }
                else  {
                    dp[i]=Math.max(dp[map.get(e)-1]+i-(int)map.get(e)+1,Math.max(dp[i-1],dp[map1.get(e)-1]+i-(int)map1.get(e)+1 ));//dp选择出情况1,2,3的最大值
                    if(map.get(e)!=map1.get(e))dp[i]=Math.max(dp[i], dp[map1.get(e)]+i-map1.get(e));//情况四的最大值
                    map1.put(e, i);}//更新上一次出现的位置
            }
            System.out.println(dp[n]);
        }
            
    }
}

顺便记录一下这场打完后成功晋级1200分成为学员选手

你可能感兴趣的:(java,开发语言,算法)