"字节跳动杯"2018中国大学生程序设计竞赛-女生专场

(6/11)施工施工...

 

A.口算训练 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6287

 

题解给的根号的分解素因子,其实能够做到log,然后维护每个因子在序列中出现的位置,每次二分查找就好了,zz的我最开始写了个3个log的线段树,被卡成狗了

 

跑得飞快系列233333

 

代码:

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int MAXN=1e5+5;
int a[MAXN],nxt[MAXN];
bool vis[MAXN];
vector<int> pos[MAXN];
void init()
{
	nxt[1]=1;
	for(int i=2;i<MAXN;i++)
	{
		if(vis[i]) continue;
		nxt[i]=i;
		for(int j=i+i;j<MAXN;j+=i)
		{
			vis[j]=true;
			if(nxt[j]==0) nxt[j]=i;
		}
	}
}
inline char nc()
{
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x)
{
	char c=nc();x=0;
	for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
void solve()
{
	int n,m;
	rea(n);rea(m);
	for(int i=1;i<MAXN;i++) pos[i].clear();
	for(int i=1;i<=n;i++)
	{
		rea(a[i]);
		int x=a[i];
		while(x!=1)
		{
			pos[nxt[x]].pb(i);
			x/=nxt[x];
		}
	}
	while(m--)
	{
		int l,r,d;
		rea(l);rea(r);rea(d);
		int now=nxt[d],cnt=0;
		bool flag=true;
		while(d!=1&&flag)
		{
			while(nxt[d]==now) cnt++,d/=nxt[d];
			int left=lower_bound(pos[now].begin(),pos[now].end(),l)-pos[now].begin();
			int right=upper_bound(pos[now].begin(),pos[now].end(),r)-pos[now].begin();
			int val=right-left;
			if(val<cnt) flag=false;
			now=nxt[d],cnt=0;
		}
		if(flag) puts("Yes");
		else puts("No");
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int T;
	init();
	rea(T);
	while(T--)
	{
		solve();
	}
	return 0;
}

B.缺失的数据范围

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6288

 

直接int128暴力就行了

 

代码:

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
ll a,b,k;
bool judge(ll x)
{
	ll cnt=0;
	ll now=1;
	while(now<x)
	{
		cnt++;
		now<<=1;
	}
	__int128 tot=1;
	for(int i=1;i<=a;i++)
	{
		tot*=x;
		if(tot>k) return false;
	}
	for(int i=1;i<=b;i++)
	{
		tot*=cnt;
		if(tot>k) return false;
	}
	return true;
}
void solve()
{
	scanf("%lld%lld%lld",&a,&b,&k);
	ll l=0,r=1000000000000000000LL;
	ll ans=0;
	while(l<=r)
	{
		ll mid=(l+r)>>1;
		if(judge(mid))
		{
			ans=mid;
			l=mid+1;
		}
		else
		{
			r=mid-1;
		}
	}
	printf("%lld\n",ans);
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		solve();
	}
	return 0;
}

D.奢侈的旅行

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6290

 

将所有的花费相加之后,发现最终的花费只和到达终点的等级有关,所以我们只要保证到达终点的等级越低越好就行,然后我们发现,经过每条边有一个最高等级,所以只要在最短路的过程中,判断某条边能不能经过即可

 

代码:

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int MAXN=100010;
const double eps=1e-8;
int cnt=0;
int sgn(double x)
{
	if(fabs(x)<eps) return 0;
	return x>0?1:-1;
}
struct qnode
{
	int v;
	ll c;
	qnode(int _v=0,ll _c=0):v(_v),c(_c){}
	bool operator <(const qnode &r)const
	{
		return c>r.c;
	}
};
struct Edge
{
	int u,v,nxt;
	double lim;
	ll cost;
	Edge(){}
	Edge(int _u,int _v,ll _cost,int _nxt,double _lim):u(_u),v(_v),cost(_cost),nxt(_nxt),lim(_lim){}
};
Edge E[MAXN*4];
bool book[MAXN],vis[MAXN];
int head[MAXN];
ll dist[MAXN];
void init()
{
	cnt=0;
	memset(head,-1,sizeof(head));
}
void Dijkstra(int n,int start)//点的编号从0开始 
{
	memset(vis,false,sizeof(vis));
	for(int i=1;i<=n;i++)dist[i]=INF;
	priority_queue<qnode>que;
	while(!que.empty())que.pop();
	dist[start]=1;
	que.push(qnode(start,1));
	qnode tmp;
	while(!que.empty())
	{
		tmp=que.top();
		que.pop();
		int u=tmp.v;
		if(vis[u])continue;
		vis[u]=true;
		for(int i=head[u];~i;i=E[i].nxt)
		{
			int v=E[i].v;
			int cost=E[i].cost;
			if(sgn(dist[u]-E[i].lim)>0) continue;
			if(!vis[v]&&dist[v]>dist[u]+cost)
			{
				dist[v]=dist[u]+cost;
				que.push(qnode(v,dist[v]));
			}
		}
	}
}
void addedge(int u,int v,ll w,double lim)
{
	E[cnt]=Edge(u,v,w,head[u],lim);
	head[u]=cnt++;
}
void solve()
{
	int n,m;
	init();
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int u,v,a,b;
		double lim;
		scanf("%d%d%d%d",&u,&v,&a,&b);
		if(b==0) lim=INF; 
		else lim=1.0*a/((1LL<<b)-1);
		addedge(u,v,a,lim);
	}
	Dijkstra(n,1);
	int ans=-1;
	ll tot=dist[n];
	if(tot==INF)
	{
		puts("-1");
		return ;
	}
	while(tot)
	{
		tot>>=1;
		ans++;
	}
	printf("%d\n",ans);
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		solve();
	}
	return 0;
}

F.赛题分析

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6292

 

非常适合老年选手水平的输入输出题目

 

代码:

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const int MAXN=505;
int a[MAXN],b[MAXN];
void solve()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
		scanf("%d",&b[i]);
	
	printf("Shortest judge solution: ");
	if(n>=1) printf("%d bytes.\n",*min_element(a+1,a+1+n));
	else printf("N/A bytes.\n");
	printf("Shortest team solution: ");
	if(m>=1) printf("%d bytes.\n",*min_element(b+1,b+1+m));
	else printf("N/A bytes.\n");

}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int T;
	scanf("%d",&T);
	for(int _=1;_<=T;_++)
	{
		printf("Problem %d:\n",_+1000);
		solve();
	}
	return 0;
}

H.SA-IS后缀数组

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6294

 

直接从后往前扫就行了,如果相邻的两个字母相等,本质上就是比较上一次相比较的两个后缀,然后就有线性的做法了

 

代码:

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const int MAXN=1e6+5;
char s[MAXN];
int ans[MAXN];
void solve()
{
	int n;
	scanf("%d",&n);
	scanf("%s",s+1);
	ans[n]=1;
	for(int i=n-1;i>=1;i--)
	{
		if(s[i]<s[i+1]) ans[i]=0;
		else if(s[i]>s[i+1]) ans[i]=1;
		else ans[i]=ans[i+1];
	}
	for(int i=1;i<n;i++)
		if(ans[i]) printf(">");
		else printf("<");
	puts("");
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		solve();
	}
	return 0;
}

K.CCPC直播

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6297

 

超高校级输出输出题目

 

代码:

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const string Running="Running";
const string FB="FB";
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		string rk,name,id,st;
		cin>>rk;
		for(int i=0;i<3-rk.size();i++)
			printf(" ");
		cout<<rk;
		printf("|");
		cin>>name;
		cout<<name;
		for(int i=name.size();i<16;i++)
			printf(" ");
		printf("|");
		cin>>id;
		cout<<id;
		printf("|");
		cin>>st;
		printf("[");
		if(st==Running)
		{
			int cnt;
			scanf("%d",&cnt);
			for(int i=1;i<=cnt;i++)
				printf("X");
			for(int i=cnt;i<10;i++)
				printf(" ");
		}
		else if(st==FB)
		{
			for(int i=0;i<4;i++)
				printf(" ");
			printf("AC*");
			for(int i=7;i<10;i++)
				printf(" ");
		}
		else
		{
			for(int i=0;i<4;i++)
				printf(" ");
			cout<<st;
			for(int i=4+st.size();i<10;i++)
				printf(" ");
		}
		printf("]\n");
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值