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<<'\n';
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\n",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\n",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\n";
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\n";
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]<<'\n'<<sb[1]<<'\n'<<sb[2]<<endl;
30                         return 0;
31                     }
32                 }
33             }
34     cout<<"0\n";
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",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\n");
21         else
22         {
23             while(x<=0)x+=p/gc;
24             printf("%lld\n",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\n",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\n",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\n",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\n",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\n",maxx);
25     }
26     return 0;
27 }
J

posted on 2020-03-27 23:06  大桃桃  阅读(573)  评论(0编辑  收藏  举报

导航