zoukankan      html  css  js  c++  java
  • TZOJ 挑战题库随机训练07

    点击题号跳转

    A4586 B3342 C6104 D2013 E1752

    F4708 G3604 H6148 I1433 J1861

    A.最小二乘法回到顶部

    题意

    给个函数,求偏导

    题解

    高等数学题,过程就不列了,计算可得,复杂度O(1)

    k=(Σ(xy)-ΣxΣy/n)/(-(Σx)^2/n+Σ(x^2))

    b=(Σy-kΣx)/n

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main(){
     5     int n;
     6     while(scanf("%d",&n)!=EOF){
     7         double sumx=0,sumx2=0,sumy=0,sumxy=0,x,y;
     8         for(int i=1;i<=n;i++){
     9             scanf("%lf%lf",&x,&y);
    10             sumx+=x,sumy+=y,sumxy+=x*y,sumx2+=x*x;
    11         }
    12         double k=(sumxy-sumx*sumy/n)/(-sumx*sumx/n+sumx2);
    13         double b=(sumy-k*sumx)/n;
    14         printf("%.1f %.1f
    ",k,b);
    15     }
    16     return 0;
    17 }
    A

    B.Children’s Queue回到顶部

    题意

    长度为n的序列放0和1,所有的1必须有相邻的1,问方案数,n<=1000

    题解

    dp[i]表示长度为i的合法方案数

    第i个位置放0,那么前i-1个无所谓,dp[i-1]

    第i个位置放1,因为要连续,i-1和i-2都放1,dp[i-2]

    其实还有一种情况,第i个位置放1,如果前面不合法,放两个1也会导致合法,那么就相当于第i-3放0,i-2放1,相当于不合法,然后放两个连续的1使其合法,就相当于放0111,dp[i-4]

    dp[i]=dp[i-1]+dp[i-2]+dp[i-4],复杂度O(1000)

    代码

     1 import java.math.BigInteger;
     2 import java.util.*;
     3 
     4 public class Main {
     5 
     6     public static void main(String[] args) {
     7 
     8         BigInteger[] big = new BigInteger[1005];
     9         big[0] = BigInteger.ONE;
    10         big[1] = BigInteger.ONE;
    11         big[2] = big[0].add(big[1]);
    12         big[3] = big[2].add(big[0].add(big[1]));
    13         for(int i = 4; i <= 1000; i++) {
    14             big[i] = big[i-1].add(big[i-2].add(big[i-4]));
    15         }
    16         Scanner sc = new Scanner(System.in);
    17         while(sc.hasNext()) {
    18             int n = sc.nextInt();
    19             System.out.println(big[n]);
    20         }
    21     }
    22 }
    B

    C.Island Transport回到顶部

    题意

    一张图(u,v,w),从左下开始,到右上,w表示容量,问最多能运多少,N,M<=100000

    题解

    一看就是网络流,但是N,M这么大怎么办?莽呗,复杂度O(你的模板复杂度)

    代码

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<queue>
      6 #define INF 0x3f3f3f3f
      7 using namespace std;
      8 const int maxn=100005;
      9 const int maxx=200005;
     10 int edge;
     11 int to[maxx],flow[maxx],nex[maxx];
     12 int head[maxn];
     13 
     14 void addEdge(int v,int u,int cap)
     15 {
     16     to[edge]=u,flow[edge]=cap,nex[edge]=head[v],head[v]=edge++;
     17     to[edge]=v,flow[edge]=cap,nex[edge]=head[u],head[u]=edge++;
     18 }
     19 int vis[maxn];
     20 int pre[maxn];
     21 bool bfs(int s,int e)
     22 {
     23     queue<int> que;
     24     pre[s]=-1;
     25     memset(vis,-1,sizeof(vis));
     26     que.push(s);
     27     vis[s]=0;
     28     while(!que.empty())
     29     {
     30         int u=que.front();
     31         que.pop();
     32         for(int i=head[u];~i;i=nex[i])
     33         {
     34             int v=to[i];
     35             if(vis[v]==-1&&flow[i])
     36             {
     37                 vis[v]=vis[u]+1;
     38                 if(v==e)
     39                     return true;
     40                 que.push(v);
     41             }
     42 
     43         }
     44     }
     45     return false;
     46 }
     47 int dfs(int s,int t,int f)
     48 {
     49     if(s==t||!f)
     50         return f;
     51     int r=0;
     52     for(int i=head[s];~i;i=nex[i])
     53     {
     54         int v=to[i];
     55         if(vis[v]==vis[s]+1&&flow[i])
     56         {
     57             int d=dfs(v,t,min(f,flow[i]));
     58             if(d>0)
     59             {
     60                 flow[i]-=d;
     61                 flow[i^1]+=d;
     62                 r+=d;
     63                 f-=d;
     64                 if(!f)
     65                     break;
     66             }
     67         }
     68     }
     69     if(!r)
     70         vis[s]=INF;
     71     return r;
     72 }
     73 
     74 int maxFlow(int s,int e)
     75 {
     76     int ans=0;
     77     while(bfs(s,e))
     78         ans+=dfs(s,e,INF);
     79     return ans;
     80 }
     81 
     82 void init()
     83 {
     84     memset(head,-1,sizeof(head));
     85     edge=0;
     86 }
     87 
     88 int main(){
     89     int t,x,y,w,n,m,s,e,maxI,minI;
     90     scanf("%d",&t);
     91     while(t--){
     92         init();
     93         scanf("%d%d%d%d",&n,&m,&x,&y);
     94         s=e=1;
     95         maxI=minI=x;
     96         for(int i=2;i<=n;i++){
     97             scanf("%d%d",&x,&y);
     98             if(maxI<x)e=i,maxI=x;
     99             if(minI>x)s=i,minI=x;
    100         }
    101         while(m--){
    102             scanf("%d%d%d",&x,&y,&w);
    103             addEdge(x,y,w);
    104         }
    105         int ans=maxFlow(s,e);
    106         printf("%d
    ",ans);
    107     }
    108     return 0;
    109 }
    C

    D.Problem Bee回到顶部

    题意

    给俩坐标A和B,蜂巢正六边形,给你个边长d,A要移动到B,如果AB在同一蜂巢直接移动过去,如果在不同蜂巢,A需要移动到中心,每次只能移动到相邻蜂巢,到达B蜂巢中心后再移动到B,蜂巢总中心在(0,0)

    题解

    数学题,先算出A和B在哪个蜂巢,再计算出需要移动几个蜂巢,最后加上A到中心和B到中心的距离

    通过计算可得,x变化量为3d/2,y变化量为sqrt(3)d/2,算出A处在x的第几块,通过奇偶算出A处在y的第几块,然后计算周围的6个蜂巢得到A到底在哪个蜂巢中

    同理计算出B,复杂度O(1)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int dx[]={0,0,1,1,-1,-1};
     4 int dy[]={2,-2,1,-1,1,-1};
     5 double d;
     6 void changes(double realx,double realy,double &x1,double &y1){
     7     double minn=(x1-realx)*(x1-realx)+(y1-realy)*(y1-realy);
     8     double truex=x1,truey=y1;
     9     for(int i=0;i<6;i++){
    10         double rx1=x1+dx[i]*(3*d/2);
    11         double ry1=y1+dy[i]*(sqrt(3.0)*d)/2;
    12         double val=(rx1-realx)*(rx1-realx)+(ry1-realy)*(ry1-realy);
    13         //if(i==3)printf("%.3f %.3f %.3f
    ",rx1,ry1,val);
    14         if(val<minn){
    15             minn=val;
    16             truex=rx1,truey=ry1;
    17         }
    18     }
    19     x1=truex,y1=truey;
    20 }
    21 int main(){
    22     double x1,y1,x2,y2;
    23     while(scanf("%lf%lf%lf%lf%lf",&d,&x1,&y1,&x2,&y2)!=EOF){
    24         //printf("%.3f %.3f %.3f %.3f %.3f
    ",d,x1,y1,x2,y2);
    25         if(x1==0&&y1==0&&x2==0&&y2==0)break;
    26         int b1=x1*2/(3*d),b2=x2*2/(3*d);
    27         int e1=y1*2/(d*sqrt(3.0)),e2=y2*2/(d*sqrt(3.0));
    28         if(b1%2==1&&e1%2==0)e1++;
    29         else if(b1%2==0&&e1%2==1)e1++;
    30         if(b2%2==1&&e2%2==0)e2++;
    31         else if(b2%2==0&&e2%2==1)e2++;
    32         //printf("%d %d %d %d
    ",b1,b2,e1,e2);
    33         if(b1==b2&&e1==e2){
    34             printf("%.3f
    ",sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)));
    35         }else{
    36             double b1x=b1*3*d/2;
    37             double b2x=b2*3*d/2;
    38             double b1y=e1*sqrt(3.0)*d/2;
    39             double b2y=e2*sqrt(3.0)*d/2;
    40             changes(x1,y1,b1x,b1y);
    41             changes(x2,y2,b2x,b2y);
    42             //(b1x,b1y)->(b2x,b2y)
    43             //printf("(%.3f,%.3f) (%.3f,%.3f)
    ",b1x,b1y,b2x,b2y);
    44             int move=fabs(b2x-b1x)*2/(3*d);
    45             printf("%.3f
    ",move*d*sqrt(3.0)+sqrt((x1-b1x)*(x1-b1x)+(y1-b1y)*(y1-b1y))+sqrt((x2-b2x)*(x2-b2x)+(y2-b2y)*(y2-b2y)));
    46         }
    47     }
    48     return 0;
    49 }
    D

    E.Tree Recovery回到顶部

    题意

    给前序中序求后序,n<30

    题解

    递归建树,dfs(L1,R1,L2,R2)代表前序中的[L1,R1],中序中的[L2,R2]

    前序第一个数一定是根,然后在中序中找到根的下标,左右两半分开,复杂度O(n)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n;
     5 char s1[30],s2[30];
     6 int dfs(int L1,int R1,int L2,int R2){
     7     if(L1>R1)return 0;
     8     char root=s1[L1];int p=L2;
     9     while(root!=s2[p])p++;
    10     int cnt=p-L2;
    11     dfs(L1+1,L1+cnt,L2,p-1);
    12     dfs(L1+cnt+1,R1,p+1,R2);
    13     printf("%c",root);
    14     return root;
    15 }
    16 int main(){
    17     while(scanf("%s%s",s1,s2)!=EOF){
    18         n=strlen(s1);
    19         dfs(0,n-1,0,n-1);
    20         printf("
    ");
    21     }
    22     return 0;
    23 }
    E

    F.小孩子的扑克牌游戏回到顶部

    题意

    A和B各有两张扑克,问谁的和离10最近,相同和大的赢

    题解

    求和判一下绝对值,复杂度O(1)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main(){
     5     int a,b,c,d;
     6     while(cin>>a>>b>>c>>d){
     7         int e=abs(10-a-b);
     8         int f=abs(10-c-d);
     9         if(e==f&&a+b==c+d)cout<<"2 2
    ";
    10         else if(e<f||a+b<c+d)cout<<"4 0
    ";
    11         else cout<<"0 4
    ";
    12     }
    13     return 0;
    14 }
    F

    G.The Table回到顶部

    题意

    n行m列,问哪一列乘积最大,相同输出m大的,n<=1000,m<=20

    题解

    大数相乘处理一下就行了,复杂度O(nm)

    代码

     1 import java.math.BigInteger;
     2 import java.util.*;
     3 
     4 public class Main {
     5 
     6     public static void main(String[] args) {
     7 
     8         BigInteger[] big = new BigInteger[25];
     9 
    10         Scanner sc = new Scanner(System.in);
    11         while(sc.hasNext()) {
    12             int m = sc.nextInt();
    13             int n = sc.nextInt();
    14             BigInteger b;
    15             for (int i = 1; i <= m; i++)
    16                 big[i] = BigInteger.ONE;
    17             for (int i = 1; i <= n; i++) {
    18                 for (int j = 1; j <= m; j++) {
    19                     b = sc.nextBigInteger();
    20                     big[j] = big[j].multiply(b);
    21                 }
    22             }
    23             int id = 1;
    24             BigInteger maxx = big[1];
    25             for (int i = 2; i <= m; i++) {
    26                 if (maxx.compareTo(big[i]) <= 0) {
    27                     maxx = big[i];
    28                     id = i;
    29                 }
    30             }
    31             System.out.println(id);
    32         }
    33     }
    34 }
    G

    H.求和回到顶部

    题意

    矩阵求和,除去最后一列,最后一行,副对角线,n<=100

    题解

    两个for,判一下i=n-1,j=n-1,i=n-j+1,复杂度O(n^2)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main(){
     5     int n,x;
     6     while(cin>>n){
     7         int sum=0;
     8         for(int i=1;i<=n;i++)
     9             for(int j=1;j<=n;j++){
    10                 cin>>x;
    11                 if(i==n||j==n||i==n-j+1)continue;
    12                 sum+=x;
    13             }
    14         cout<<sum<<'
    ';
    15     }
    16     return 0;
    17 }
    H

    I.正整数解回到顶部

    题意

    计算方程x^2+y^2+z^2=num的最小正整数解,num<=10000

    题解

    100^2=10000,那么直接三个for,复杂度O(<<100^3)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main(){
     5     int num,x,y,z;
     6     e:while(cin>>num){
     7         for(int i=1;i<=num;i++){
     8             if(i*i>num)break;
     9             for(int j=i;j<=num;j++){
    10                 if(i*i+j*j>num)break;
    11                 for(int k=j;k<=num;k++){
    12                     if(i*i+j*j+k*k>num)break;
    13                     if(i*i+j*j+k*k==num){
    14                         cout<<i<<" "<<j<<" "<<k<<'
    ';
    15                         goto e;
    16                     }
    17                 }
    18             }
    19         }
    20     }
    21     return 0;
    22 }
    I

    J.Perfect Cubes回到顶部

    题意

    函数a^3+b^3+c^3=n,求<=n的所有解,n<=100

    题解

    4个for,10^2=100,复杂度O(n*10^3)

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main(){
     5     int n,x;
     6     while(scanf("%d",&n)!=EOF){
     7         for(int i=6;i<=n;i++){
     8             for(int j=2;j<=n;j++){
     9                 if(i*i*i<j*j*j)break;
    10                 for(int k=j;k<=n;k++){
    11                     if(i*i*i<j*j*j+k*k*k)break;
    12                     for(int l=k;l<=n;l++){
    13                         if(i*i*i<j*j*j+k*k*k+l*l*l)break;
    14                         if(i*i*i==j*j*j+k*k*k+l*l*l){
    15                             printf("Cube = %d, Triple = (%d,%d,%d)
    ",i,j,k,l);
    16                         }
    17                     }
    18                 }
    19             }
    20         }
    21     }
    22     return 0;
    23 }
    J
  • 相关阅读:
    JDBC 删除数据两种方式,PreparedStatement表示预编译的 SQL 语句的对象,防止sql注入
    MySQL 主键外键
    JDBC 增删改查
    MySQL数据库语句
    反射
    如何安装、配置、登陆MySQL
    如何干净卸除MySQL数据库
    IO流总结
    字符流五种读写 字符流 BufferedWriter BufferedReader 带缓冲区的字符流
    单例模式
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/12630849.html
Copyright © 2011-2022 走看看