HDU-6223-Infinite Fraction Path

**Infinite Fraction Path**
Time Limit: 6000/3000 MS (Java/Others)
Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 6221 Accepted Submission(s): 1209

Problem Description

The ant Welly now dedicates himself to urban infrastructure. He came to the kingdom of numbers and solicited an audience with the king. He recounted how he had built a happy path in the kingdom of happiness. The king affirmed Welly’s talent and hoped that this talent can help him find the best infinite fraction path before the anniversary.
The kingdom has N cities numbered from 0 to N - 1 and you are given an array D[0 … N - 1] of decimal digits (0 ≤ D[i] ≤ 9, D[i] is an integer). The destination of the only one-way road start from the i-th city is the city labelled (i2 + 1)%N.
A path beginning from the i-th city would pass through the cities u1,u2,u3, and so on consecutively. The path constructs a real number A[i], called the relevant fraction such that the integer part of it is equal to zero and its fractional part is an infinite decimal fraction with digits D[i], D[u1], D[u2], and so on.
The best infinite fraction path is the one with the largest relevant fraction

Input
The input contains multiple test cases and the first line provides an integer up to 100 indicating to the total numberof test cases.
For each test case, the first line contains the integer N (1 ≤ N ≤ 150000). The second line contains an array ofdigits D, given without spaces.
The summation of N is smaller than 2000000.

Output
For each test case, you should output the label of the case first. Then you are to output exactly N characters which are the first N digits of the fractional part of the largest relevant fraction.

Sample Input

4
3
149
5
12345
7
3214567
9
261025520

Sample Output

Case #1: 999
Case #2: 53123
Case #3: 7166666
Case #4: 615015015

题目链接:HUD-6223

题目大意

这道题的意思是给你一串字符串长度为n,从0到n-1,然后第一个位置只能通往(i*i+1)%n,这个位置然后让你输出从一个位置开始跳然后链接每个位置上的字符形成一个长度为n的字符串的字典序最大;

解题思路

毫无疑问这个题肯等要从最大的字符看是跳,但是如果最大的数字有好几个呢?那我们只有一个一个的慢慢的遍历了,但是直接遍历的话肯定会超时的,那我们该如何做呢?
我们可以用BFS加上优先队列去解决
1.因为比较字符串的字典序肯定是由前到后一个个的比较,那么我们就刚好可以有BFS吧这些字符串 进行分层,
2.但是分层的是后肯定要借助优先队列了,我们首先把最大的字符串设为第一层放入优先队列,优先队列里面的元素先按照层数由小到大出队,当层数相同时按照谁大谁先出队,然后借助BFS进行分层 每次每次放入队列的元素的层数为当前的层数+1,这样就解决了。
大致的思路有了那么就是处理起来的细节了和外加优化,
1, 当遍历到的这个位置对应的字符比队列里面的小,那么我们就可以直接结束了,因为在遍历下去也没有意义了,只会浪费时间。
2, 但遍历同一层的时候对数组进行标记,一旦这个数组被标记过了那么这个也不用遍历了,因为一个一个位置能通往的下一个位置也是固定不变的,这个字符串已经和当前的这个状态重复了。
3, 当遍历到的这个位置对应的字符比队列里面的大,那么我们就把这个一层的这个位置给更新了然后直接结束了。
4, 每当更新到下一层的时候一定要把标记数组给清空了,防止不同层数的数都是不同位置的当前最大数,比如说第一层最大是9,但是这个位置通往的下一个位置对应的数还是9,下一层还是9,这样的话如果你不更行,就会出错;
5, 因为数据太大了如果用memset初始化数组的话肯定会超时的,所以自己初始化数组,还有个小坑点就是 i*i会爆 int 所以存的时候直接用 long long

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
char s[200000];//初始化字符串数组 
int vis[200000];//是否被标记过 
char mm[200000];//结果答案字符数组 
int f[200000];//记录位置 
int ma=0;//当前记录位置的数组里面中有几个元素 
ll n,t;
struct Node{
	ll id;//这个节点对应的字符串的位置 
	int st;//层数 
	Node(ll x=0,int y=0)// 这个是为了在队列放元素的时候直接有 Node (x,y);这样用 
	{
		id=x;
		st=y;
	}
	friend bool operator <(Node a,Node b)//定义 优先队列里面的排列顺序
	{
		if(a.st==b.st) return s[a.id]<s[b.id];
		return a.st>b.st;	
	}
};

priority_queue<Node>que;

void bfs()
{
	int flag=-1;//表示当前是第几层 
	while(!que.empty())
	{
		Node now=que.top();
		que.pop();
		if(now.st!=flag)//如果层数变化了,那么就要初始化标记数组了 
		{
			flag=now.st;//更新当前的位置 
			while(ma)
			{
				vis[f[--ma]]=0;//初始化为零 
			}
		}
		if(now.st<n&&mm[now.st]<=s[now.id]&&!vis[now.id ])//当前位置没被标记果 
		{												//且当前的位置和结果数组的当前层数相同时放入队列中 
			vis[now.id]=1;			// 防止重复处理,将该位置标记 
			f[ma++]=now.id;        //当前这一层的数别标记的个数加一,并且记录该位置,为了方便下次初始化 
			mm[now.st]=s[now.id];//该位置的字符满足了题目要求防如结果里面这样其实也是每次都会更新结果数组的值只是等新的值都是大于等于以前的值得 
			que.push(Node((now.id*now.id+1)%n,now.st+1));//将该位置放入队列中 
		}
	}
}

int main()
{
	
	scanf("%d",&t);
	int K=1;
	while(t--)
	{
		scanf("%d%s",&n,s);
		char maxn=0;
		for(int i=0;i<n;i++)
		{
			if(s[i]>maxn) maxn=s[i];//找出最大的元素 
		}
		for(int i=0;i<n;i++) que.push(Node(i,0));//把最大的元素全部作为第一层放入优先队列里 
		bfs();//开始搜索 
		printf("Case #%d: ",K++);
        for(ll i=0;i<n;i++)
            putchar(mm[i]);
        puts("");
        for(ll i=0;i<n;i++)//每次操作完以后都要把结果数组给初始化因为是多组输入,这样避免这次结果对下次的结果造成影响 
            mm[i]=0;
	}
	return 0;
}

全部评论

相关推荐

真烦好烦真烦:豆包润色了自己没看看吗,再说了,都说豆包是愚蠢且勤快的大学生,ds才是聪明的研究生,怎么敢让豆包写论文的
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务