2019牛客多校第五场 A,B,C,E,F,G,H,I,

A-digits 2

题目链接:https://ac.nowcoder.com/acm/contest/885/A

题目大意:给出一个n<=100,求满足条件的整数:1.数位之和时n的倍数。2.这个数可以被n整除。3.这个数不超过10000位。

思路:n个n,完美符合条件

ACCode:

int main(){
	int T;scanf("%d",&T);
	while(T--){
		int n;scanf("%d",&n);
		for(int i=1;i<=n;++i) printf("%d",n);printf("\n");
	}
}

但是我一直不知道,为什么这份代码会错:n个n依次相加。总共也就100个数据,我都跑出来了,没有问题,但是还是WA。

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand(unsigned)time(NULL));rand();
   
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
   
#define ll long long
#define Pii pair<int,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
   
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)
 
int B[MAXN];
 
int main(){
    //int T=100;
    int T;scanf("%d",&T);
    while(T--){
        //int n=(100-T);
        int n;scanf("%d",&n);
        if(n<10){
            printf("%d\n",n);
            continue;
        }
        if(n==100){
            for(int i=1;i<=100;++i) printf("1");printf("00\n");
            continue;
        }
        clean(B,0);
        int a=n/10,b=n%10;
        for(int i=1;i<=n;++i) B[i]=b;
        for(int i=1;i<=n;++i) B[i+1]+=a;
        for(int i=1;i<=n;++i){
            if(B[i]/10) B[i+1]+=B[i]/10;
            B[i]%=10;
        }
        int top=n+1;
        while(B[top]/10){
            B[top+1]=B[top]/10;
            B[top]%=10;
            ++top;
        }
        for(int i=top;i>=1;--i) printf("%d",B[i]);printf("\n");
    }
}

B-generator 1

题目链接:https://ac.nowcoder.com/acm/contest/885/B

10为底的矩阵快速幂:https://blog.csdn.net/henucm/article/details/98492753

C-generator 2

题目链接:https://ac.nowcoder.com/acm/contest/885/C

数论队友:https://blog.csdn.net/henucm/article/details/99682328

E-independent set 1

题目链接:https://ac.nowcoder.com/acm/contest/885/E

文少的位元状压DP:https://blog.csdn.net/henu_1710252529/article/details/102639844

F-maximum clique 1

题目链接:https://ac.nowcoder.com/acm/contest/885/F

题目大意:n个数,选择一个最大数目的集合满足集合内任意两个数之间至少有两个数位不同。求这个集合的最大,输出点。

思路:将任意两个数最多一位不同的数连边,强行构造出一个二分图,按位数的奇偶划分成两个点集。跑二分图匹配。得到的匹配数量就是最大的点集。至于寻找路径,我们跑完最大流后,从剩下的残留网络中从起点开始,所有能找到的就是典籍中的点。

ACCode:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand(unsigned)time(NULL));rand();
   
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
   
#define ll long long
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
   
const int MAXN=5e3+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)
 
struct Node{
    int v,val,nxt;
    Node(int _v=0,int _val=0,int _nxt=0){
        v=_v;val=_val;nxt=_nxt;
    }
};
Node Edge[MAXN*100];
int Head[MAXN],Cur[MAXN],Ecnt;
int Dis[MAXN];
int Vis[MAXN],Belong[MAXN];
int A[MAXN];
int Ans[MAXN],tot;
int n,S,T;
 
void Intt(){
	clean(Head,-1);Ecnt=0;
}
void AddEdge(int u,int v,int val){
    Edge[Ecnt]=Node(v,val,Head[u]);
    Head[u]=Ecnt++;
}
int Judge(int a,int b){
    a^=b;
    if((a&(a-1))==0) return 1;
    return 0;
}
int SA(int a){
    int Cnt=0;
    while(a){
        if(a&1) Cnt++;
        a>>=1;
    }return Cnt&1;
}
int BFS(){
    clean(Dis,-1);Dis[S]=0;
    queue<int> que;que.push(S);
    while(que.size()){
        int u=que.front();que.pop();
        if(u==T) return 1;
        for(int i=Head[u];i+1;i=Edge[i].nxt){
            int v=Edge[i].v;
            if(Dis[v]==-1&&Edge[i].val>0){
                Dis[v]=Dis[u]+1;
                que.push(v);
            }
        }
    }return 0;
}
int DFS(int u,int low){
    if(u==T||low==0) return low;
    int res=0;
    for(int &i=Cur[u];i+1;i=Edge[i].nxt){
        int v=Edge[i].v;
        if(Dis[v]==Dis[u]+1&&Edge[i].val>0){
            int f=DFS(v,min(low-res,Edge[i].val));
            Edge[i].val-=f;Edge[i^1].val+=f;
            res+=f;
            if(res==low) break;
        }
    }return res;
}
int Dinic(){
    int Ans=0;
    while(BFS()){
        for(int i=0;i<=T;++i) Cur[i]=Head[i];
        Ans+=DFS(S,INF32);
    }return Ans;
}
void DFSPath(int u,int fa=-1){
    Vis[u]=1;
    for(int i=Head[u];i+1;i=Edge[i].nxt){
        int v=Edge[i].v;
        if(Edge[i].val==0||v==fa||Vis[v]==1) continue;
		DFSPath(v,u);
    }
}
int main(){
    Intt();scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&A[i]);
    for(int i=1;i<=n;++i){
        for(int j=i+1;j<=n;++j){
            if(Judge(A[i],A[j])){
                int x=SA(A[i]),y=SA(A[j]);
                if(x==1&&y==0){
                    AddEdge(i,j,1);AddEdge(j,i,0);
                    //printf("正%d %d\n",A[i],A[j]);
                }
                else if(x==0&&y==1){
                    AddEdge(j,i,1);AddEdge(i,j,0);
                    //printf("反%d %d\n",A[i],A[j]);
                }
            }
        }
    }S=0;T=n+1;
    for(int i=1;i<=n;++i){
        if(SA(A[i])){
        	Belong[i]=1;
            AddEdge(S,i,1);AddEdge(i,S,0);
        }
        else{
        	Belong[i]=2;
            AddEdge(i,T,1);AddEdge(T,i,0);
        }
    }
    int MaxLow=Dinic();
    printf("%d\n",n-MaxLow);
    DFSPath(S);
//    for(int i=1;i<=n;++i){
//    	printf("A[i]=%d Vis=%d Belong%d\n",A[i],Vis[i],Belong[i]);
//	}
    tot=0;
    for(int i=1;i<=n;++i){
    	if(Belong[i]==1&&Vis[i]==1) Ans[++tot]=A[i];
    	else if(Belong[i]==2&&Vis[i]==0) Ans[++tot]=A[i];
	}
	for(int i=1;i<=tot;++i) printf("%d ",Ans[i]);printf("\n");
}
 
/*
 
6
4 3 8 2 6 5
 
*/

G-subsequence 1

题目链接:https://ac.nowcoder.com/acm/contest/885/G

数论队友:https://blog.csdn.net/henucm/article/details/98518989

H-subsequence 2

题目链接:https://ac.nowcoder.com/acm/contest/885/H

题目大意:长度为n的一个隐藏字符串,每次能显示两种字母,求原来的字符串。

思路:将以显示的字母按顺序建立拓扑图。进行拓扑排序。同一个字符的不同数量也要作区分。直接进行拓扑排序即可。

ACCode:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand(unsigned)time(NULL));rand();
     
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
     
#define ll long long
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
     
const int MAXN=1e6+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)
 
struct Node{
    int v,nxt;
    Node(int _v=0,int _nxt=0){
        v=_v;nxt=_nxt;
    }
};
Node Edge[MAXN<<2];
int Head[MAXN<<2],Ecnt;
int InDeg[MAXN<<2];
PII Pos[MAXN];
map<PII,int> CI;int Icnt;//处理出来,ch的第几个对应的int
map<int,char> IC;
char S[MAXN];
int Ans[MAXN<<2],tot;
int n,m;
 
void Intt(){
    clean(Head,-1);Ecnt=0;
    clean(InDeg,0);
    Icnt=0;
    for(int i=0;i<26;++i){
        for(int j=1;j<=n;++j){
            CI[make_pair(i,j)]=++Icnt;
            IC[Icnt]='a'+i;
        }
    }tot=0;
}
void AddEdge(int u,int v){
    Edge[Ecnt]=Node(v,Head[u]);
    Head[u]=Ecnt++;
}
void Solve(){
    queue<int> que;
    for(int i=1;i<=tot;++i){
        if(InDeg[Ans[i]]==0) que.push(Ans[i]);
    }tot=0;
    while(que.size()){
        int u=que.front();que.pop();
        Ans[++tot]=u;
        for(int i=Head[u];i+1;i=Edge[i].nxt){
            int v=Edge[i].v;
            --InDeg[v];
            if(InDeg[v]==0) que.push(v);
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);Intt();
    for(int i=1;i<=m;++i){
        for(int j=i+1;j<=m;++j){
            int len;scanf("%s%d",&S,&len);//
            if(len==0) continue;//读入数据没有要注意!!! 
            char a=S[0],b=S[1];
            int cnta=0,cntb=0;
            scanf("%s",&S);
            for(int k=0;k<len;++k){//得到每个字符的id 
                if(S[k]==a) Pos[k]=make_pair(a-'a',++cnta);
                else Pos[k]=make_pair(b-'a',++cntb);
                Ans[++tot]=CI[Pos[k]];//将得到的id记录 
            }
            for(int k=0;k<len-1;++k){//连接边 
                int u=CI[Pos[k]],v=CI[Pos[k+1]];
                AddEdge(u,v);InDeg[v]++;
            }
        }
    }
    sort(Ans+1,Ans+1+tot);//去重
    int tmp=1;
    for(int i=2;i<=tot;++i){
        if(Ans[i]!=Ans[tmp]) Ans[++tmp]=Ans[i];
    }tot=tmp;//共Ans中tot个元素
    Solve();
    if(tot!=n) printf("-1\n");
    else{
        for(int i=1;i<=tot;++i){
            printf("%c",IC[Ans[i]]);
        }printf("\n");
    }
}

I-three points 1

题目链接:https://ac.nowcoder.com/acm/contest/885/I

题目大意:在一个高为h,宽为w的矩形内放入一个三边分别为a,b,c的三角形,输出一组顶点(注意顶点顺序)

思路:枚举三点在任意的位置。

ACCode:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand(unsigned)time(NULL));rand();
     
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
     
#define ll long long
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define PDI pair<double,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
     
const int MAXN=1e4+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-10;
//unsigned register
// ios::sync_with_stdio(false)
 
struct Point{
    double x,y;
    Point(double _x=0,double _y=0){
        x=_x;y=_y;
    }
};
Point A,B,C;
double l[5];
double W,H;
 
double GetAng(double a,double b,double c){
    double ans=a*a+b*b-c*c;
    ans/=(2.0*a*b);
    return acos(ans);
}
int InRec(Point X){
    if(X.x>-EPS&&X.x<W+EPS){
        if(X.y>-EPS&&X.y<H+EPS){
            return 1;
        }
    }return 0;
}
int Judge(int i,int j,int k){
    A=Point(0,0);
    if(l[i]<H+EPS) B=Point(0,l[i]);
    else B=Point(sqrt(l[i]*l[i]-H*H),H);
    double Ang1=GetAng(l[i],B.y,B.x);
    double Ang2=GetAng(l[i],l[k],l[j]);
    C=Point(l[k]*sin(Ang1+Ang2),l[k]*cos(Ang1+Ang2));
    return InRec(C);
}
int main(){
    int T;scanf("%d",&T);
    while(T--){
        scanf("%lf%lf",&W,&H);
        for(int i=1;i<=3;++i) scanf("%lf",&l[i]);
         
        if(Judge(1,2,3)) printf("%.12lf %.12lf %.12lf %.12lf %.12lf %.12lf\n",B.x,B.y,A.x,A.y,C.x,C.y);
        else if(Judge(1,3,2)) printf("%.12lf %.12lf %.12lf %.12lf %.12lf %.12lf\n",A.x,A.y,B.x,B.y,C.x,C.y);
        else if(Judge(2,1,3)) printf("%.12lf %.12lf %.12lf %.12lf %.12lf %.12lf\n",B.x,B.y,C.x,C.y,A.x,A.y);
        else if(Judge(2,3,1)) printf("%.12lf %.12lf %.12lf %.12lf %.12lf %.12lf\n",A.x,A.y,C.x,C.y,B.x,B.y);
        else if(Judge(3,1,2)) printf("%.12lf %.12lf %.12lf %.12lf %.12lf %.12lf\n",C.x,C.y,B.x,B.y,A.x,A.y);
        else if(Judge(3,2,1)) printf("%.12lf %.12lf %.12lf %.12lf %.12lf %.12lf\n",C.x,C.y,A.x,A.y,B.x,B.y);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值