TOYOTA SYSTEMS Programming Contest 2022(AtCoder Beginner Contest 279)A-F题(暂定)

FA,w是两个v是一个 送分题

#include<bits/stdc++.h>
using namespace std ;
#define maxn 400100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
char in[maxn] ; 
signed main(){
//    freopen("test.in" , "r" , stdin) ;
//    freopen("test.out" , "w" , stdout) ;\
    
    scanf("%s" , in + 1) ; 
    int len = strlen(in + 1) ; 
    int sum = 0 ; 
    for(int i = 1 ; i <= len ; i++){
        if(in[i] == 'v') sum++ ; 
        else sum += 2 ; 
    }
    printf("%lld" , sum) ; 
    return 0 ;
}

B.数据范围很小 直接暴力判断即可

#include<bits/stdc++.h>
using namespace std ;
#define maxn 400100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
char s[maxn] , t[maxn] ; 
int slen , tlen ; 
bool check(int st){
    if(st + tlen - 1 > slen) return 0 ; 
    for(int i = 1 ; i <= tlen ; i++)
        if(s[st + i - 1] != t[i]) return 0 ; 
    return 1 ; 
}
signed main(){
//    freopen("test.in" , "r" , stdin) ;
//    freopen("test.out" , "w" , stdout) ;
    scanf("%s" , s + 1) ; scanf("%s" , t + 1) ; 
    slen = strlen(s + 1) ; tlen = strlen(t + 1) ; 
    if(tlen > slen){
        printf("No") ; 
        return 0 ; 
    }
    for(int i = 1 ; i <= slen ; i++){
        if(check(i)){
            printf("Yes") ; 
            return 0 ; 
        }
    }
    printf("No") ; 
    return 0 ;
}

C.判断前面的每一竖列是否能在后面找到一样的 对于每一个竖列 计算哈希值以及有多少个 然后和后面进行比较即可

#include<bits/stdc++.h>
using namespace std ;
#define maxn 400100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
int hsh[maxn] ; 
const int mod = 998244353 ; 
int bse = 12281 ; 
char in[maxn] ; 
int num[maxn] ; 
int h , w  ;
int pos(int i , int j){
    return (i - 1) * w + j ; 
}
map<int,int> mp1 ; 
map<int,int> mp2 ; 
int vt[maxn] , cnt ; 
signed main(){
//    freopen("test.in" , "r" , stdin) ;
//    freopen("test.out" , "w" , stdout) ;
    h = read() , w = read() ; 
    for(int i = 1 ; i <= h ; i++){
        scanf("%s" , in + 1) ; 
        for(int j = 1 ; j <= w ; j++)
            if(in[j] == '#')
                num[pos(i , j)] = 3 ; 
            else num[pos(i , j)] = 7 ; 
    }
    for(int i = 1 ; i <= w ; i++){
        int sum = 0 ; 
        for(int j = 1 ; j <= h ; j++)
            sum = (sum * bse + num[pos(j , i)]) % mod ; 
//        printf("sum : %lld \n") 
        if(!mp1[sum]) mp1[sum] = 1 , vt[++cnt] = sum; 
        else mp1[sum]++ ; 
    }
//    printf("cnt : %lld \n" , cnt) ; 
    for(int i = 1 ; i <= h ; i++){
        scanf("%s" , in + 1) ; 
        for(int j = 1 ; j <= w ; j++)
            if(in[j] == '#')
                num[pos(i , j)] = 3 ; 
            else num[pos(i , j)] = 7 ; 
    }
    for(int i = 1 ; i <= w ; i++){
        int sum = 0 ; 
        for(int j = 1 ; j <= h ; j++)
            sum = (sum * bse + num[pos(j , i)]) % mod ; 
        if(!mp2[sum]) mp2[sum] = 1; 
        else mp2[sum]++ ; 
    }
    for(int i = 1 ; i <= cnt ; i++)
        if(mp1[vt[i]] != mp2[vt[i]]){
            printf("No") ; 
            return 0 ; 
        }
    printf("Yes") ; 
    return 0 ;
}

 

D.求导之后进行二分找到最后一个使导函数大于0的点和第一个使导函数小于0的点 然后比较一下两边的值 

#include<bits/stdc++.h>
using namespace std ;
#define maxn 400100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
double A , B ;  
signed main(){
//    freopen("test.in" , "r" , stdin) ;
//    freopen("test.out" , "w" , stdout) ;
    cin >> A >> B ; 
    double C = A / (2.0 * B) ; 
    int l = 0 , r = pow(10 , 18) ; 
    int mid = (l + r) / 2 , ans = 0 ; 
    while(l <= r){
        if(pow(1 + mid , 1.5) <= C) ans = mid , l = mid +  1 ; 
        else r = mid - 1 ; 
        mid = (l + r) / 2 ; 
//        printf("l : %lld  r: %lld \n" , l , r ) ; 
    }
    double ansa , ansb ; 
    ansa = B * ans + A / pow(1 + ans , 0.5) ; 
    ans++ ; 
    ansb = B * ans + A / pow(1 + ans , 0.5); 
    printf("%.10lf" , min(ansa , ansb)) ; 
    return 0 ;
}

E

首先我觉得最简单方法应该就是安哥的方法 但是我看到了一种分治的思想 我觉得也有道理 分享一下 

具体来说 对于我们要计算的一个区间[l,r] 我们需要依次考虑每一个操作缺失的情况对吧 

那么当我们在考虑[l,mid]时 右边所有的操作一定已经完成了 所以我们可以把右边的操作完成掉 然后再去计算[l,mid] 这一段 

在计算完左边的答案之后 左边的操作一定都可以完成了 然后我们再计算右边的答案 

但问题在于就这个题目来说 答案的合并我不知道如何完成 如果有能写出来的同学请帮帮我 希望得到大神指点 !

F

首先一眼并查集 很容易想到 但是唯一的难点就是插入这个地方 

如果它插入的盒子里的球没有了 那么就比较麻烦了 

所以我们每次把y并入到x中的时候 完全可以新建一个盒子 那么以后有y的话 就可以直接塞到新盒子里了 最后我们统计新盒子的实际上是谁(ans数组)以及每一个盒子现在的编号(id)就可以 

注意一下实现的细节 在代码里标注了 

#include<bits/stdc++.h>
using namespace std ;
#define maxn 900100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
int fa[maxn] , id[maxn] , ans[maxn] ; 
// id[i] 表示现在i号盒子对应的真正的编号 
// ans[i] 表示真正的编号对于的题目中的i号盒子 
//二者互相映射  
int find(int x){
    if(fa[x] == x)
        return fa[x] ; 
    return fa[x] = find(fa[x]) ; 
}
int n , q ; 
void merge(int x , int y){
    int fx = find(x) , fy = find(y) ; 
    if(fx != fy)
    fa[fy] = fx ; 
    return ; 
}
int totball , totbox ; 
signed main(){
//    freopen("test.in" , "r" , stdin) ;
//    freopen("test.out" , "w" , stdout) ;
    n = read() , q = read() ; 
    totball = n ; totbox = n + q ; // 这里新盒子的编号一定要从n+q开始 要不然可能会和小球的编号撞了 在并查集路径压缩的时候会出现混乱 
    for(int i = 1 ; i <= n + 2 * q ; i++)
        fa[i] = ans[i] = id[i] = i  ; 
    while(q--){
        int op = read() , x = read() ; 
        if(op == 1){
            int y = read() ; 
            merge(id[x] , id[y]) ; 
            totbox++ ; 
            id[y] = totbox ; ans[totbox] = y ; 
            fa[totbox] = totbox ; 
//            printf("fa[%lld] : %lld find : %lld \n" , totbox , fa[totbox] , find(totbox)) ; 
        }
        else if(op == 2){
            totball++ ; 
            fa[totball] = find(id[x]) ; 
//            printf("id[%lld] : %lld fa : %lld \n" , x , id[x] , find(id[x])) ; 
        }
        else {
            printf("%lld\n" , ans[find(x)]) ; 
        }
    }
    return 0 ;
}

 

posted @ 2022-11-26 22:08  Vellichor_zht  阅读(100)  评论(0)    收藏  举报