• TZOJ 挑战题库随机训练06


    点击题号跳转

    A1127 B5675 C5432 D5248 E4443

    F5626 G4295 H5859 I3001 J4205

    A.Java vs C++回到顶部

    题意

    给一个字符串,问是C形式还是Java形式,不合法输出Error

    题解

    有点坑,需要注意'_'在开头和某尾,Java形式不能出现'_',C形式不能出现大写,不能出现连续两个'_',复杂度O(n)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int checkjava(string s){
     5     if('A'<=s[0]&&s[0]<='Z')return false;
     6     for(int i=0;s[i];i++){
     7         if(s[i]=='_')return false;
     8     }
     9     return true;
    10 }
    11 int checkcpp(string s){
    12     if(s[0]=='_')return false;
    13     for(int i=0;s[i];i++){
    14         if('A'<=s[i]&&s[i]<='Z')return false;
    15     }
    16     for(int i=1;s[i];i++){
    17         if(s[i]=='_'&&s[i-1]=='_')return false;
    18     }
    19     if(s[s.size()-1]=='_')return false;
    20     return true;
    21 }
    22 int main(){
    23     string s;
    24     while(getline(cin,s)){
    25         if(checkjava(s)){
    26             for(int i=0;s[i];i++){
    27                 if('A'<=s[i]&&s[i]<='Z')cout<<"_"<<(char)(s[i]+32);
    28                 else cout<<s[i];
    29             }
    30         }else if(checkcpp(s)){
    31             for(int i=0;s[i];i++){
    32                 if(s[i]=='_')continue;
    33                 if(i&&s[i-1]=='_')cout<<(char)(s[i]-32);
    34                 else cout<<s[i];
    35             }
    36         }else{
    37             cout<<"Error!";
    38         }
    39         cout<<'
    ';
    40     }
    41     return 0;
    42 }
    A

    B.数据结构实验:压缩对称矩阵回到顶部

    题意

    给一个对称矩阵,存一半,给定(i,j)输出

    题解

    存下半,如果i>j那么交换两个数,下标通过观察可以知道是一个等差+一个偏移量,计算得到i*(i-1)/2+j-1

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 void Zip(int a[100][100],int n,int b[]){
     5     int i,j,index=0;
     6     for(i=0;i<n;i++)
     7         for(j=0;j<=i;j++)
     8             b[index++]=a[i][j];
     9 }
    10 int Index(int i,int j){
    11     if(i<j)swap(i,j);
    12     //printf("i=%d j=%d index=%d
    ",i,j,i*(i-1)/2+j-1);
    13     return i*(i-1)/2+j-1;
    14 }
    B

    C.数据结构实验:二叉树倾斜度回到顶部

    题意

    给一棵树,倾斜度就是每个节点左右儿子子树和的差的绝对值

    题解

    一个dfs,dfs的同时再写两个dfs用于统计左右子树的和,由于N只有512,这样做也不会超时,复杂度O(n^2)

    代码

     1 int lson(struct TreeNode* root){
     2     int sum=0;
     3     if(root->left!=NULL)sum+=root->left->val+lson(root->left);
     4     if(root->right!=NULL)sum+=root->right->val+lson(root->right);
     5     return sum;
     6 }
     7 int rson(struct TreeNode* root){
     8     int sum=0;
     9     if(root->left!=NULL)sum+=root->left->val+rson(root->left);
    10     if(root->right!=NULL)sum+=root->right->val+rson(root->right);
    11     return sum;
    12 }
    13 int findTilt(struct TreeNode* root){
    14     int sum=0;
    15     int lsum=(root->left!=NULL?root->left->val+lson(root->left):0);
    16     int rsum=(root->right!=NULL?root->right->val+rson(root->right):0);
    17     //printf("%d %d %d %d
    ",root->val,lsum,rsum,sum);
    18     sum+=abs(rsum-lsum);
    19     if(root->left!=NULL)sum+=findTilt(root->left);
    20     if(root->right!=NULL)sum+=findTilt(root->right);
    21     return sum;
    22 }
    C

    D.C++实验:栈类模板回到顶部

    题意

    实现一个栈模板

    题解

    template<class T,int Size>

    class MyStack{

    private:

    public:

    }

    这个套路,也不是很难,注意这里top为空的时候,需要throw "Empty",复杂度O(1)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 template<class T,int SIZE>
     5 class Stack {
     6     int a[11],top;
     7 public:
     8     Stack(){
     9         top=0;
    10     }
    11     void Push(int x){
    12         if(top==10)cout<<"Full
    ";
    13         else a[++top]=x;
    14     }
    15     int Top(){
    16         string s="Empty";
    17         if(top==0) throw s;
    18         else return a[top];
    19     }
    20     void Pop(){
    21         if(top==0)cout<<"Empty
    ";
    22         else top--;
    23     }
    24 };
    D

    E.Crosswords回到顶部

    题意

    给6个长度为3的字符串,问是否可以选出3个使得,横竖出现的恰好是6个字符串

    题解

    模拟,暴力判断,复杂度O(6^4)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 string sb[10],s[10];
     5 map<string,int>sma,smb;
     6 bool check(){
     7     smb=sma;
     8     string prep;
     9     for(int i=0;i<3;i++){
    10         if(smb[sb[i]]>0)smb[sb[i]]--;
    11         else return 0;
    12         prep=sb[0][i];prep+=sb[1][i];prep+=sb[2][i];
    13         if(smb[prep]>0)smb[prep]--;
    14         else return 0;
    15     }
    16     return 1;
    17 }
    18 int main(){
    19     for(int i=0;i<6;i++)cin>>s[i],sma[s[i]]++;
    20     int f[]={0,1,2,3,4,5};
    21     for(int i=0;i<6;i++)
    22         for(int j=0;j<6;j++)
    23             for(int k=0;k<6;k++){
    24                 if(i!=j&&j!=k){
    25                     sb[0]=s[i];
    26                     sb[1]=s[j];
    27                     sb[2]=s[k];
    28                     if(check()){
    29                         cout<<sb[0]<<'
    '<<sb[1]<<'
    '<<sb[2]<<endl;
    30                         return 0;
    31                     }
    32                 }
    33             }
    34     cout<<"0
    ";
    35     return 0;
    36 }
    E

    F.Kannyi 的easy problem回到顶部

    题意

    给个n,计算[1,n]中2^n-1有多少个能被7整除

    题解

    每左移三位可以被7整除,所以答案就是n/3,复杂度O(1)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define LL long long
     5 int main(){
     6     LL n;
     7     while(scanf("%lld",&n)!=EOF,n){
     8         printf("%lld
    ",n/3);
     9     }
    10     return 0;
    11 }
    F

    G.Modular Inverse回到顶部

    题意

    ax同余1(mod p),给定a((0,1000]),p([0,1000])求出x

    题解

    很明显的exgcd,ax+by=gcd(a,b)

    构造ax+py=1,当gcd(a,p)不等于1时无解

    求出特解为x,由于要保证x>0,可以不断加上p/gcd(a,p),复杂度O(logn)

    PS:ax同余1(mod p)

    ->ax%p=(py+1)%p

    ->ax%p=py%p+1

    ->ax+py同余1(mod p)(+和-一样)

    ax+by=c有解的条件是c%gcd(a,p)是否等于0

    那么上面有解的条件就是gcd(a,p)是否等于1

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 ll exgcd(ll a,ll b,ll &x,ll &y)
     5 {
     6     if(b==0){x=1;y=0;return a;}
     7     ll r=exgcd(b,a%b,x,y);
     8     ll t=x;x=y;y=t-a/b*y;
     9     return r;
    10 }
    11 int main()
    12 {
    13     int t;
    14     scanf("%d",&t);
    15     while(t--)
    16     {
    17         ll a,p,x,y;
    18         scanf("%lld%lld",&a,&p);
    19         ll gc=exgcd(a,p,x,y);
    20         if(gc!=1)printf("Not Exist
    ");
    21         else
    22         {
    23             while(x<=0)x+=p/gc;
    24             printf("%lld
    ",x);
    25         }
    26     }
    27     return 0;
    28 }
    G

    H.桃子的可达数回到顶部

    题意

    f[x]=x+1去掉末尾的0,问f[f[x]]循环会出现多少个不同的数

    题解

    模拟,存入unordered_map判重,复杂度O(100)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int t;
     7     scanf("%d",&t);
     8     while(t--){
     9         int n;
    10         scanf("%d",&n);
    11         unordered_map<int,int>ma;
    12         do{
    13             if(ma.count(n))break;
    14             ma[n]=1;
    15             n++;
    16             while(n!=0&&n%10==0)n/=10;
    17         }while(1);
    18         printf("%d
    ",ma.size());
    19     }
    20     return 0;
    21 }
    H

    I.Lagrange's Four-Square Theorem回到顶部

    题意

    计算有多少个不超过4个平方数之和等于n([1,32768])

    题解

    可知182*182>32768,那么直接182^4+一些剪枝,复杂度O(14089082≈1.4e7)

    PS:dp[i][j]代表值为i,需要j个数的平方相加得到,转移dp[i][j+1]+=dp[i-val*val][j],复杂度O(15752792≈1.5e7),感谢zzl

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n,dp[32768];
     5 int main(){
     6     for(int i=1;i<=182;i++){
     7         dp[i*i]++;
     8         for(int j=i;j<=182;j++){
     9             if(i*i+j*j>32768)break;
    10             dp[i*i+j*j]++;
    11             for(int k=j;k<=182;k++){
    12                 if(i*i+j*j+k*k>32768)break;
    13                 dp[i*i+j*j+k*k]++;
    14                 for(int l=k;l<=182;l++){
    15                     if(i*i+j*j+k*k+l*l>32768)break;
    16                     dp[i*i+j*j+k*k+l*l]++;
    17                 }
    18             }
    19         }
    20     }
    21     while(scanf("%d",&n)!=EOF,n){
    22         printf("%d
    ",dp[n]);
    23     }
    24     return 0;
    25 }
    I
     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int N=1<<15;
     5 int f[N+5][5];
     6 int main() {
     7     f[0][0]=1;
     8     for(int i=1;i<=182;i++) {
     9         for(int j=i*i;j<=N;j++) {
    10             for(int k=0;k<4;k++) {
    11                 f[j][k+1]+=f[j-i*i][k];
    12             }
    13         }
    14     }
    15     int n;
    16     while(~scanf("%d",&n),n) {
    17         printf("%d
    ",f[n][1]+f[n][2]+f[n][3]+f[n][4]);
    18     }
    19     return 0;
    20 }
    I by zzl

    J.New Game回到顶部

    题意

    n([1,100000])次操作,每次给一对数(a,b),a、b均小于等于100,问每次操作后,求出某个两两匹配,输出ai+bj最大值最小

    题解

    可以发现a、b很小,肯定从a、b下手,让ai+bj最小,那么肯定是ai最小的+bj最大的,ai第二小+bj第二大

    那么就可以通过pa指针和pb指针,每次都比较,复杂度O(100n)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n,a[105],b[105],c[105],d[105];
     5 int main(){
     6     scanf("%d",&n);
     7     for(int i=1;i<=n;i++){
     8         int x,y;
     9         scanf("%d%d",&x,&y);
    10         a[x]++;b[y]++;
    11         for(int j=1;j<=100;j++)c[j]=a[j],d[j]=b[j];
    12         int pa=1,pb=100,maxx=0;
    13         while(pa<=100&&c[pa]==0)pa++;
    14         while(pb>=1&&d[pb]==0)pb--;
    15         while(pa<=100&&pb>=1){
    16             if(c[pa]>d[pb])c[pa]-=d[pb],d[pb]=0;
    17             else if(c[pa]<d[pb])d[pb]-=c[pa],c[pa]=0;
    18             else c[pa]=d[pb]=0;
    19             //printf("i=%d pa=%d pb=%d
    ",i,pa,pb);
    20             maxx=max(maxx,pa+pb);
    21             while(pa<=100&&c[pa]==0)pa++;
    22             while(pb>=1&&d[pb]==0)pb--;
    23         }
    24         printf("%d
    ",maxx);
    25     }
    26     return 0;
    27 }
    J
  • 相关阅读:
    线程

    线程
    【java】彩票中奖码生成器:java.util.Random里的方法public int nextInt(int bound)
    【java】java.lang.Math:public static long round(double a)和public static int round(float a)
    【java】对象克隆protected Object clone() throws CloneNotSupportedException
    【java】对象变成垃圾被垃圾回收器gc收回前执行的操作:Object类的protected void finalize() throws Throwable
    【java】计算一段代码执行时长java.lang.System类里的public static long currentTimeMillis()方法
    【java】多线程同步生产者消费者问题
    【java】多线程同步死锁
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/12584846.html
Copyright © 2020-2023  润新知