zoukankan      html  css  js  c++  java
  • 2019牛客多校第五场

    A.digits 2

    传送:https://ac.nowcoder.com/acm/contest/885/A

    题意:构造一个不超过$10^4$位的十进制数,且满足这个数是$n$的倍数,且每一位的和是$n$的倍数。

    数据范围:$1<=n<=100$。

    分析:直接构造$n$个$n$即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main(){
     4     int t,x;scanf("%d",&t);
     5     while (t--){
     6         scanf("%d",&x);
     7         for (int i=0;i<x;i++) printf("%d",x);
     8         printf("
    ");
     9     }
    10     return 0;
    11     
    12 } 
    A

    B.generator 1

    传送:https://ac.nowcoder.com/acm/contest/885/B

    题意:已知$x_0,x_1,a,b$,且$x_i=a*x{i-1}+b*x_{i-2}$。求解$x_n%mod$。

    数据范围:$1<=x_0,x_1,a,b<=10^9,1<=n<=10^{10^6},1<=mod<=2 imes 10^9$。

    分析:开始考虑矩阵快速幂。但$n$范围过大,开始考虑把高精度$n$分解为二进制数,然后做矩阵快速幂。

    但是进制转换会tle。正解是十进制快速幂+矩阵快速幂。

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 typedef long long ll;
     5 const int N=1e6+10;
     6 struct mat{ll a[2][2];};
     7 ll x0,x1,a,b,mod; char n[N];
     8 mat mat_mul(mat x,mat y){
     9     mat ans;
    10     memset(ans.a,0,sizeof(ans.a));
    11     for (int i=0;i<2;i++){
    12         for (int j=0;j<2;j++)
    13         for (int k=0;k<2;k++)
    14             (ans.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod)%=mod;
    15     }
    16     return ans;
    17 }
    18 ll mat_pow(){
    19     mat c,res;
    20     c.a[0][0]=a;c.a[0][1]=b;c.a[1][0]=1;c.a[1][1]=0;
    21     res.a[0][0]=x1; res.a[1][0]=x0; res.a[0][1]=res.a[1][1]=0;
    22     int len=strlen(n);
    23     for (int i=len-1;i>=0;i--){
    24         int kk=n[i]-'0'; mat tmp=c;
    25         for (int j=0;j<kk;j++) res=mat_mul(c,res);
    26         for (int j=0;j<9;j++) c=mat_mul(c,tmp);
    27     }
    28     return res.a[1][0]%mod;
    29 }
    30 int main(){
    31     scanf("%lld%lld%lld%lld",&x0,&x1,&a,&b);
    32     scanf("%s",&n);
    33     scanf("%lld",&mod);
    34     ll ans=mat_pow();
    35     printf("%lld
    ",ans);
    36     return 0;
    37 }
    B

    F.maximum clique 1

    传送:https://ac.nowcoder.com/acm/contest/885/F

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<queue>
      6 #define mem(a,b) memset(a,b,sizeof a)
      7 #define en '
    '
      8 #define maxn 5123
      9 using namespace std;
     10 typedef long long ll;
     11 template<class T>void rd(T &x)
     12 {
     13     x=0;int f=0;char ch=getchar();
     14     while(ch<'0'||ch>'9')  {f|=(ch=='-');ch=getchar();}
     15     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
     16     x=f?-x:x;
     17     return;
     18 }
     19  
     20 const int inf =1<<29;
     21 int head[maxn];
     22 int n,m,tot,maxflow,s,t,a[maxn];
     23 queue<int>q;
     24 int d[maxn];
     25 struct node{
     26 int v,nxt,w;
     27 }edge[80*maxn];
     28  
     29 void add(int u,int v,int w){
     30     edge[++tot].nxt=head[u];head[u]=tot;edge[tot].v=v;edge[tot].w=w;
     31     edge[++tot].nxt=head[v];head[v]=tot;edge[tot].v=u;edge[tot].w=0;
     32 }
     33 bool bfs(){
     34 mem(d,0);
     35     while(q.size())q.pop();
     36     q.push(s);
     37     d[s]=1;
     38     while(q.size()){
     39         int x=q.front();q.pop();
     40         for(int i=head[x];i;i=edge[i].nxt){
     41                 if(edge[i].w and !d[edge[i].v]){
     42                     q.push(edge[i].v);
     43                     d[edge[i].v]=d[x]+1;
     44                     if(edge[i].v==t){
     45                         return 1;
     46                     }
     47                 }
     48         }
     49     }
     50     return 0;
     51 }
     52 int dinic(int x,int flow){
     53     if(x==t)return flow;
     54     int rest=flow,k;
     55     for(int i=head[x];i and rest ;i=edge[i].nxt){
     56         if(edge[i].w and d[edge[i].v]==d[x]+1){
     57             k=dinic(edge[i].v,min(rest,edge[i].w));
     58             if(!k)d[edge[i].v]=0;
     59             edge[i].w-=k;
     60             edge[i^1].w+=k;
     61             rest-=k;
     62         }
     63     }
     64     return flow -rest;
     65 }
     66 bool ok(int x,int y){
     67 int tem=x^y;
     68 int cnt=0;
     69 while(tem){
     70     if(tem&1)cnt+=1;
     71     tem>>=1;
     72 }
     73 if(cnt==1)return 1;
     74 return 0;
     75 }
     76 bool ji(int x){
     77 int res=0;
     78 while(x){
     79     res+=(x&1);
     80     x>>=1;
     81 }
     82 return res&1;
     83 }
     84 bool vis[maxn];
     85 bool zuo[maxn];
     86 signed main()
     87 {
     88     #ifdef local
     89     freopen("input2.txt","r",stdin);
     90     #endif
     91     int T;
     92     //cin>>T;
     93     T=1;
     94     int cas=0;
     95     while(T--){
     96         while(cin>>n){
     97         tot=1;
     98         mem(edge,0);
     99         mem(head,0);
    100        ///___________________________________
    101         s=5001;
    102         t=5002;
    103        for(int i=1;i<=n;i++){
    104             rd(a[i]);
    105        }
    106        for(int i=1;i<=n;i++){
    107             for(int j=i+1;j<=n;j++){
    108                 if(ok(a[i],a[j])){
    109                     if(ji(a[i]))
    110                     add(i,j,inf);
    111                         else add(j,i,inf);
    112                 }
    113             }
    114        }
    115        for(int i=1;i<=n;i++){
    116             if(ji(a[i])){
    117                     zuo[i]=1;
    118                 add(s,i,1);
    119             }else{
    120                 add(i,t,1);
    121             }
    122        }
    123  
    124         ///___________________________________
    125     int flow=0;
    126     maxflow=0;
    127     while(bfs()){
    128         while(flow=dinic(s,inf))maxflow+=flow;
    129     }
    130     cout<<n-maxflow<<en;
    131     for(int i=1;i<=n;i++){
    132         if(zuo[i] and d[i]){
    133             cout<<a[i]<<' ';
    134         }
    135         if(!zuo[i] and !d[i]){
    136             cout<<a[i]<<' ';
    137         }
    138     }cout<<en;
    139   }
    140 }
    141   return 0;
    142 }
    F

    G.subsequence 1

    传送:https://ac.nowcoder.com/acm/contest/885/G

    题意:给定两个数字字符串$s$和$t$,求解$s$串内有多少个子序列大于$t$。答案$%998244353$。

    数据范围:$1<=m<=n<=3000$。

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=3050;
     5 const ll mod=998244353;
     6 int n,m;
     7 ll ans;
     8 char S[maxn],T[maxn];
     9 ll ini[maxn][maxn],sum[maxn][maxn],tag[maxn];
    10 void init()
    11 {
    12     ini[0][0]=1;
    13     for (int i=1;i<=3000;i++)
    14     {
    15         ini[i][i]=ini[i][0]=1;
    16         for (int j=1;j<i;j++)
    17         {
    18             ini[i][j]=(ini[i-1][j]+ini[i-1][j-1])%mod;
    19             sum[i][j]=(sum[i][j-1]+ini[i][j])%mod;
    20         }
    21         sum[i][i]=(ini[i][i]+sum[i][i-1])%mod;
    22     }
    23 }
    24 void initt()
    25 {
    26     ans=0;
    27     memset(tag,0,sizeof(tag));
    28     tag[0]=1;
    29 }
    30 void solve()
    31 {
    32     initt();
    33     for (int i=1;i<=m;i++)
    34     {
    35         for (int j=n;j>=1;j--)
    36         {
    37             if(S[i]>T[j])
    38                 {if(m-i>=n-j) ans=(ans+ini[m-i][n-j]*tag[j-1])%mod; }
    39             else if(S[i]==T[j])
    40                 {if(m-i>=n-j) tag[j]=(tag[j]+tag[j-1])%mod;}
    41         }
    42     }
    43     for (int i=1;i<=m;i++)
    44         if(m-i>=n && S[i]>'0')
    45         {
    46             ll tmp=sum[m-i][m-i]-sum[m-i][n-1];
    47             ans=((ans+tmp)%mod+mod)%mod;
    48         }
    49     printf("%lld
    ",ans);
    50 }
    51 int main()
    52 {
    53     init();
    54     int t;scanf("%d",&t);
    55     while (t--)
    56     {
    57         scanf("%d%d",&m,&n);
    58         scanf("%s",S+1);scanf("%s",T+1);
    59         solve();
    60     }
    61     return 0;
    62 }
    G

    H.subsequence 2

    传送:https://ac.nowcoder.com/acm/contest/885/H

    题意:有一个目标字符串,每次给定一个字符串$s$,然后可以得到一个长度为$m$的字符串$t$,代表$s$串内所有字母在目标字符串内出现的情况。求解目标字符串。

    数据范围:$1<=n<=10^4,2<=m<=10,0<=len<=n$。

    分析:建图+topo排序。考虑若干个字母出现的相对位置,有一个先后关系,建图,然后跑一个topo序。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e4;
     4 char a[maxn+1000];
     5 map<char,int> mp;
     6 int f[30],ans[maxn+1000],tag[30];
     7 bool flag;
     8 int head[26*maxn+1000],ind[26*maxn+1000];
     9 int tot,n,m;
    10 struct node{int u,v,nxt;} g[26*maxn+1000];
    11 void add(int u,int v)
    12 {
    13     g[tot]={u,v,head[u]};
    14     head[u]=tot++;
    15 }
    16  
    17 int cal()
    18 {
    19     int res=0;
    20     queue<int> Q;
    21     for (int i=0;i<26;i++)
    22         for (int j=1;j<=tag[i];j++)
    23             if(!ind[i*maxn+j]) {Q.push(i*maxn+j);ans[++res]=i;}
    24     while (!Q.empty())
    25     {
    26         int x=Q.front();Q.pop();
    27         // cout<<x<<endl;
    28         for (int i=head[x];i;i=g[i].nxt)
    29         {
    30             int y=g[i].v;ind[y]--;
    31             // cout<<y<<' '<<ind[y]<<endl;
    32             if(!ind[y]) {ans[++res]=y/maxn;Q.push(y);}
    33         }
    34     }
    35     // cout<<res<<endl;
    36     return res;
    37 }
    38 void update()
    39 {
    40     mp.clear();
    41     scanf("%s",a);
    42     int st=strlen(a);
    43     for (int i=0;i<st;i++) mp[a[i]]++;
    44     int x;scanf("%d",&x);
    45     if(!x) return;
    46     scanf("%s",a);
    47     for (int i=0;i<30;i++) f[i]=0;
    48     for (int i=0;i<x;i++)
    49     {
    50         if(mp[a[i]]==0) flag=false;
    51         f[a[i]-'a']++;
    52         if(i==0) continue;
    53         if(a[i-1]!=a[i])
    54         {
    55             int x1=(a[i-1]-'a')*maxn+f[a[i-1]-'a'];
    56             int x2=(a[i]-'a')*maxn+f[a[i]-'a'];
    57             add(x1,x2);
    58             ind[x2]++;
    59         }
    60     }
    61     for (int i=0;i<26;i++)
    62     {
    63         if(f[i] && !tag[i]) tag[i]=f[i];
    64         else if(f[i] && f[i]!=tag[i]) flag=false;
    65     }
    66 }
    67 void solve()
    68 {
    69     int tmp=0;
    70     for (int i=0;i<26;i++)
    71     {
    72         tmp+=tag[i];
    73         for (int j=1;j<tag[i];j++)
    74         {
    75             int xx=i*maxn+j;
    76             add(xx,xx+1);
    77             ind[xx+1]++;
    78         }
    79     }
    80     if(tmp!=n) flag=false;
    81     // for (int i=1;i<=tot;i++) cout<<i<<' '<<head[i]<<' '<<g[i].v<<endl;
    82     if(!flag) {printf("-1
    ");return;}
    83      
    84     int sum=cal();
    85     if(sum!=n) {printf("-1
    ");return;}
    86     for (int i=1;i<=sum;i++) printf("%c",(char)ans[i]+'a');
    87     printf("
    ");return;
    88 }
    89 int main()
    90 {
    91     scanf("%d%d",&n,&m);
    92     int kk=(m-1)*m/2;
    93     flag=true;tot=1;
    94     while (kk--) update();
    95     solve();
    96     return 0;
    97 }
    H

    I.three points 1

    传送:https://ac.nowcoder.com/acm/contest/885/I

    题意:构造三个点$X,Y,Z$,且满足条件:$|XY|=a,|XZ|=b,|YZ|=c,0<=x<=w,0<=y<=h$。

    分析:考虑一个三角形能够在一个矩形内能够放下的所有情况。即固定一个点然后考虑另外两个点的位置。

    枚举所有情况即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const double eps=1e-8;
     4 int sgn(double x){
     5     if (fabs(x)<eps) return 0;
     6     if (x<0) return -1;
     7     return 1;
     8 }
     9 struct point{
    10     double x,y;
    11     point(){}
    12     point(double _x,double _y){
    13         x=_x; y=_y;
    14     }
    15 }aa[5];
    16 double w,h,a,b,c;
    17 bool check(point z){
    18     if (sgn(z.x-0)>=0 && sgn(z.x-w)<=0 && sgn(z.y-0)>=0 && sgn(z.y-h)<=0) return true;
    19     return false;
    20 }
    21 int solve(double a,double b,double c,int x,int y,int z){
    22     aa[x]=point(0.0,0.0);
    23     if (a<=w) aa[y]=point(a,0.0);
    24     else{
    25         double kk=sqrt(a*a-w*w);
    26         aa[y]=point(w,kk);
    27     }
    28     double d=(a*a+b*b-c*c)/(2*a*b);
    29     d=acos(d);
    30     double dd=atan(aa[y].y/aa[y].x);
    31     d+=dd;
    32     aa[z]=point(b*cos(d),b*sin(d));
    33     if (check(aa[z])){
    34         for (int i=1;i<=3;i++){
    35             if(i!=3) printf("%.12f %.12f ",aa[i].x,aa[i].y);
    36             else printf("%.12f %.12f
    ",aa[i].x,aa[i].y);
    37         }
    38         return 1;
    39     } 
    40     return 0;
    41 }
    42 int main(){
    43     int t;scanf("%d",&t);
    44     while (t--){
    45         scanf("%lf%lf%lf%lf%lf",&w,&h,&a,&b,&c);
    46         //枚举六种可能
    47         if (solve(a,b,c,1,2,3)) continue;
    48         if (solve(a,c,b,2,1,3)) continue;
    49         if (solve(b,a,c,1,3,2)) continue;
    50         if (solve(b,c,a,3,1,2)) continue;
    51         if (solve(c,a,b,2,3,1)) continue;
    52         if (solve(c,b,a,3,2,1)) continue;    
    53     } 
    54     return 0;
    55 } 
    I
  • 相关阅读:
    HDU:2767-Proving Equivalences(添边形成连通图)
    POJ:1330-Nearest Common Ancestors(LCA在线、离线、优化算法)
    HDU:1269-迷宫城堡(tarjan模板)
    Xml 丶json丶 C/S KVO 数据库 SQL 数据持久化 复杂对象 集合视图综合
    项目穿越记
    SDP (Session Description Protocol)
    shell脚本实现查找文件夹下重复的文件,并提供删除功能
    HDU 2896 病毒侵袭 (AC自动机)
    项目启动那些事儿
    C++ 完美破解九宫格(数独)游戏
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11289511.html
Copyright © 2011-2022 走看看