牛客小白月赛21(已AK)

比赛地址:传送门

A Audio

题解:这道题给定三个点,求一个点的位置,这个点到给出的三个点的距离相等,计算几何,也就相当于求出三个点构成的圆的圆心,可以搞出两条垂直平分线做下。
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const db EPS=1e-9;
inline int sign(db a){return a<-EPS?-1:a>EPS;}
inline int cmp(db a,db b){return sign(a-b);}
inline db sqr(db x){return x*x;}
struct Point{
	db x,y;
	Point(){}
	Point(db _x,db _y):x(_x),y(_y){}
	void input(){scanf("%lf%lf",&x,&y);}
	Point operator + (const Point &b)const{
		return Point(x+b.x,y+b.y);
	}
	Point operator - (const Point &b)const{
		return Point(x-b.x,y-b.y);
	}
	db operator ^ (const Point &b)const{
		return x*b.y-y*b.x;
	}
	db operator * (const Point &b)const{
		return x*b.x+y*b.y;
	}
	Point operator * (const db &k)const{
		return Point(x*k,y*k);
	}
	Point operator / (const db &k)const{
		return Point(x/k,y/k);
	}
	Point rotleft(){return Point(-y,x);}
};
struct Line{
	Point s,e;
	Line(){}
	Line(Point _s,Point _e):s(_s),e(_e){}
	Point crosspoint(Line v){
        db a1=(v.e-v.s)^(s-v.s);
        db a2=(v.e-v.s)^(e-v.s);
        return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
    }
};
int main()
{
    Point a,b,c;
	a.input();b.input();c.input();
	Point dot1=(a+b)/2,dot2=(b+c)/2;
	Point t1=Point(a-b),t2=Point(b-c);
	t1=t1.rotleft(),t2=t2.rotleft();
	Line l1=Line(dot1,dot1+t1),l2=Line(dot2,dot2+t2);
	Point r=l1.crosspoint(l2);
	printf("%.3f %.3f\n",r.x,r.y);
    return 0;
}

B Bits

题解:是个模拟题,首先汉诺塔问题的解题代码大家都很熟悉,最后可以想到的是在上面添加成分,可以把每根柱子上用个 v e c t o r vector vector来进行维护,思路清晰,代码写着也是非常流畅的。
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define pf(a) printf("%d\n",a)
#define pf2(a,b) printf("%d %d\n",a,b)
#define p_f(a) printf("%d ",a)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const db eps=1e-9;
vector<int>g[5];
int n,tot=1;
void print()
{
	tot--;
	int lim=3*(2*n+1)+4;
	rep(i,1,lim)printf("%c",'.');puts("");
	rep(i,1,3){
		printf("%c",'.');
		int mid=(2*n+1)/2+1;
		rep(j,1,2*n+1){
			if(j==mid)printf("%c",'|');
			else printf("%c",'.');
		}
	}
	printf("%c",'.');puts("");
	per(i,n,1){
		rep(j,1,3){
			printf("%c",'.');
			int h=g[j].size();
			int mid=(2*n+1)/2+1;
			rep(k,1,2*n+1){
				if(h<i){
					if(k==mid)printf("%c",'|');
					else printf("%c",'.');
				}else{
					int length=g[j][i-1];
					int l=mid-length,r=mid+length;
					if(k>=l&&k<=r)printf("%c",'*');
					else printf("%c",'.');
				}
			}
		}
		printf("%c",'.');puts("");
	}
	if(tot==0)return ;
	rep(i,1,lim)printf("%c",'-');puts("");
}
void move(int a,int b)
{
	int p=g[a].size()-1;
	g[b].pb(g[a][p]);
	g[a].erase(g[a].begin()+p);
	print();
}
void hanoi(int n,int a,int b,int c)
{
	if(n==1){
		move(a,c);
		return ;
	}
	hanoi(n-1,a,c,b);
	move(a,c);
	hanoi(n-1,b,a,c);
}
int main()
{
    sc(n);
	rep(i,1,n)tot*=2;
	per(i,n,1)g[1].pb(i);
	print();
	int a=1,b=2,c=3;
	if(n%2==0)hanoi(n,a,b,c);
	else hanoi(n,a,c,b);
    return 0;
}

C Channels

题解:使用前缀差一下就没问题了。
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
ll t1,t2;
int main()
{
    while(cin>>t1>>t2){
		t1--;
		ll res=(t2/60)*50+((t2%60)>50?50:(t2%60));
		res-=(t1/60)*50+((t1%60)>50?50:(t1%60));
		cout<<res<<endl;
	}
	    return 0;
}

D DDoS

题解:这个题题意需要仔细看看,并且输入范围也是提示了什么东西,最后也就是求一个拓扑图从 1 1 1 n n n的路径条数了。
直接拓扑 d p dp dp
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define pf(a) printf("%d\n",a)
#define pf2(a,b) printf("%d %d\n",a,b)
#define p_f(a) printf("%d ",a)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const db eps=1e-9;
const int N=1e5+5;
const int P=20010905;
vector<int>e[N];
int n,m,u,v,w,in[N],f[N];
void toposort()
{
	queue<int>q;
	q.push(1);f[1]=1;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=0;i<e[u].size();i++){
			int v=e[u][i];
			f[v]=(f[v]+f[u])%P;
			in[v]--;
			if(in[v]==0)q.push(v);
		}
	}
}
int main()
{
	sc2(n,m);
	rep(i,1,m){
		sc2(u,v);sc(w);
		e[u].pb(v);
		in[v]++;
	}
	toposort();
	pf(f[n]);
    return 0;
}

E Exams

题解:这个题四舍五入是个小trick,可见我的这篇博客

F Fool Problem

题解:打表直接找规律,证明待补。

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;

int main()
{
	string s;
	cin>>s;
	int size=s.size();
	int n=s[size-1]-'0';
	if(n%2)cout<<-1<<endl;
	else cout<<1<<endl;
    return 0;
}

G Game

题解:这个题我是这样做的,可以直接从 1 1 1 95718 95718 95718打表,对于后面的数可以进行约数分解,使用前面算出的答案来统计,因为博弈么,肯定大家都用最有策略,一旦先手能让对方输,那就必然采用这个步骤,思路详见代码。
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=95718+10;
int n,f[N];
void solve(int x)
{
    rep(i,2,ceil(sqrt(x))){
        if(x%i==0){
            if(f[i]==1&&f[x/i]==1){
                f[x]=-1;
                return ;
            }
        }
    }
    f[x]=1;
    return ;
}
int main()
{
    f[1]=f[2]=f[3]=1;
    f[4]=-1;
    rep(i,5,95718){
        solve(i);
    }
    cin>>n;
    if(f[n]==1)cout<<"Nancy"<<endl;
    else cout<<"Johnson"<<endl;
    return 0;
}

H ”Happy New Year!“

题解:送分题
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;

int main()
{
    cout<<"\"Happy New Year!\""<<endl;
    return 0;
}

I I love you

题解:可以用 d p dp dp,可以先考虑用二维 d p dp dp f [ i ] [ 1 ∼ 8 ] f[i][1\sim8] f[i][18]表示此时在第 i i i位,能构成 i l o v e y o u iloveyou iloveyou中的第 j j j个前缀的个数,那么直接递推过去就行了。
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=684594+5;
const int P=20010905;
string s;
int f[N][10];
int main()
{
    cin>>s;
    int size=s.size();
    rep(i,0,size-1)s[i]=tolower(s[i]);
    s='*'+s;
    rep(i,1,size){
        if(s[i]=='i')f[i][1]=(f[i-1][1]+1)%P;
        else f[i][1]=f[i-1][1];
        if(s[i]=='l')f[i][2]=(f[i-1][1]+f[i-1][2])%P;
        else f[i][2]=f[i-1][2];
        if(s[i]=='o')f[i][3]=(f[i-1][2]+f[i-1][3])%P,f[i][7]=(f[i-1][6]+f[i-1][7])%P;
        else f[i][3]=f[i-1][3],f[i][7]=f[i-1][7];
        if(s[i]=='v')f[i][4]=(f[i-1][3]+f[i-1][4])%P;
        else f[i][4]=f[i-1][4];
        if(s[i]=='e')f[i][5]=(f[i-1][4]+f[i-1][5])%P;
        else f[i][5]=f[i-1][5];
        if(s[i]=='y')f[i][6]=(f[i-1][5]+f[i-1][6])%P;
        else f[i][6]=f[i-1][6];
        if(s[i]=='u')f[i][8]=(f[i-1][8]+f[i-1][7])%P;
        else f[i][8]=f[i-1][8];
    }
    cout<<f[size][8]<<endl;
    return 0;
}

除此之外,直接使用一维数组进行 d p dp dp也是没有任何问题的, f [ 1 ∼ 8 ] f[1\sim8] f[18]表示当前能构成 i l o v e y o u iloveyou iloveyou的第 j j j个前缀的数目。
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define pf(a) printf("%d\n",a)
#define pf2(a,b) printf("%d %d\n",a,b)
#define p_f(a) printf("%d ",a)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const db eps=1e-9;
const int N=684594+5;
const int P=20010905;
char s[N];
int f[N];
int main()
{
    scanf("%s",s+1);
	int size=strlen(s+1);
	rep(i,1,size){
		if(s[i]=='i'||s[i]=='I')f[1]=(f[1]+1)%P;
		if(s[i]=='l'||s[i]=='L')f[2]=(f[2]+f[1])%P;
		if(s[i]=='o'||s[i]=='O')f[3]=(f[3]+f[2])%P,f[7]=(f[7]+f[6])%P;
		if(s[i]=='v'||s[i]=='V')f[4]=(f[4]+f[3])%P;
		if(s[i]=='e'||s[i]=='E')f[5]=(f[5]+f[4])%P;
		if(s[i]=='y'||s[i]=='Y')f[6]=(f[6]+f[5])%P;
		if(s[i]=='u'||s[i]=='U')f[8]=(f[8]+f[7])%P;
	}
	printf("%d\n",f[8]);
    return 0;
}

J Jelly

题解:三维 b f s bfs bfs
c o d e : code: code:

#include
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define mm(a,b) memset(a,b,sizeof(a))
#define pii pair
#define mp make_pair
#define pb push_back
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define pf(a) printf("%d\n",a)
#define pf2(a,b) printf("%d %d\n",a,b)
#define p_f(a) printf("%d ",a)
#define fi first
#define se second
#define db double
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const db eps=1e-9;
const int N=1e2+15;
int n;
char m[N][N][N];
bool flag[N][N][N];
struct date{
    int x,y,z,s;
};
int ndir[100][10]={{0,-1,0},{0,1,0},{-1,0,0},{1,0,0},{0,0,1},{0,0,-1}};
bool safe(int x,int y,int z)
{
    if(x<1||x>n)return false;
    if(y<1||y>n)return false;
    if(z<1||z>n)return false;
    if(m[x][y][z]=='*')return false;
    if(flag[x][y][z])return false;
    return true;
}
queue<date>q;
int bfs()
{
    q.push({1,1,1,1});
    flag[1][1][1]=true;
    while(!q.empty()){
        date u=q.front();
        if(u.x==n&&u.y==n&&u.z==n)return u.s;
        q.pop();
        rep(i,0,5){
            int nx=u.x+ndir[i][0],ny=u.y+ndir[i][1],nz=u.z+ndir[i][2];
            if(safe(nx,ny,nz)){
                q.push({nx,ny,nz,u.s+1});
                flag[nx][ny][nz]=true;
            }
        }
    }
    return -1;
}
int main()
{
    sc(n);
    rep(i,1,n)rep(j,1,n)scanf("%s",m[i][j]+1);
    printf("%d\n",bfs());
    return 0;
}

你可能感兴趣的:(日常code)