You Are Given a Decimal String...(CodeForces - 1202B)

题目

Suppose you have a special x-y-counter. This counter can store some value as a decimal number; at first, the counter has value 0.

The counter performs the following algorithm: it prints its lowest digit and, after that, adds either x or y to its value. So all sequences this counter generates are starting from 0. For example, a 4-2-counter can act as follows:

  1. it prints 0, and adds 4 to its value, so the current value is 4, and the output is 0;
  2. it prints 4, and adds 4 to its value, so the current value is 8, and the output is 04;
  3. it prints 8, and adds 4 to its value, so the current value is 12, and the output is 048;
  4. it prints 2, and adds 2 to its value, so the current value is 14, and the output is 0482;
  5. it prints 4, and adds 4 to its value, so the current value is 18, and the output is 04824.

This is only one of the possible outputs; for example, the same counter could generate 0246802468024 as the output, if we chose to add 2 during each step.

You wrote down a printed sequence from one of such x-y-counters. But the sequence was corrupted and several elements from the sequence could be erased.

Now you’d like to recover data you’ve lost, but you don’t even know the type of the counter you used. You have a decimal string s — the remaining data of the sequence.

For all 0≤x,y<10, calculate the minimum number of digits you have to insert in the string s to make it a possible output of the x-y-counter. Note that you can’t change the order of digits in string s or erase any of them; only insertions areallowed.

Input
The first line contains a single string s (1≤|s|≤2⋅10^6, si∈{0−9}) — the remaining data you have. It’s guaranteed that s1=0.

Output
Print a 10×10 matrix, where the j-th integer (0-indexed) on the i-th line (0-indexed too) is equal to the minimum number of digits you have to insert in the string s to make it a possible output of the i-j-counter, or −1 if there is no way to do so.

翻译一下下啦:╮(╯▽╰)╭

假设你有一个特殊的x-y计数器。该计数器可以存储一些十进制数值;首先,计数器的值为0。

计数器执行以​​下算法:它打印其最低位,然后在其值中添加x或y。因此,此计数器生成的所有序列都从0开始。例如,4-2计数器可以如下操作:

1.打印0,并将其值加4,所以当前值为4,输出为0;
2.打印4,并将其值加4,所以当前值为8,输出为04;
3.打印8,并将其值加4,所以当前值为12,输出为048;
4.打印2,并将其值加2,所以当前值为14,输出为0482;
5.它打印4,并将其值加4,因此当前值为18,输出为04824。

这只是可能的产出之一;例如,如果我们选择在每个步骤中添加2,则同一计数器可以生成0246802468024作为输出。

您从其中一个x-y计数器中记下了打印序列。但是序列被破坏了,序列中的几个元素可以被删除。

现在您想要恢复丢失的数据,但您甚至不知道您使用的计数器的类型。你有一个十进制字符串s - 序列的剩余数据。

对于所有0≤x,y <10,计算必须在字符串s中插入的最小位数,以使其成为x-y计数器的可能输出。请注意,您不能更改字符串s中的数字顺序或删除其中的任何数字;仅允许插入。

输入
第一行包含单个字符串s(1≤| s |≤2⋅10^ 6,si∈{0-9}) - 您拥有的其余数据。保证s1 = 0。

输出
打印10×10矩阵,其中第i行(第0行索引)的第j个整数(0索引)等于您必须在字符串s中插入的最小位数,以使其成为ij计数器的可能输出,如果没有办法则输出-1。

思路:这道题的思路很简单,但是解法比较巧妙~
首先,我们直到对于每个x-y计数器,要统计0-9每两个数字之间需要最少加多少个x或y才能转换,因为是10×10,所以统计不怎么耗时间,加上字符串的长度,所以肯定要用数组记录起来,关键就在于怎样判断两个数字能否转换,如果能,最少需要多少次转换,这个时候我们可以用到Floy的最短路思想,每次都有两条边走,记录每两个点之间的最短路,不就是转换的最少次数嘛,很巧妙的思想,具体看下面代码~

代码如下:(。^▽^)

#include 
using namespace std;
const int inf=0x3f3f3f3f;
int dis[10][10];//记录最短路次数
char s[2000010];//记录输入的字符串

int fun(int x,int y)
{
	memset(dis,inf,sizeof(dis));
	for(int i=0;i<=9;i++)//如果能直接到达,就让次数加1
	dis[i][(i+x)%10]=dis[i][(i+y)%10]=1;
	 
    for(int k=0;k<=9;k++)
    for(int i=0;i<=9;i++)
    for(int j=0;j<=9;j++)
    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);//这里就是最短路啦
    
    int l=strlen(s),ans=0;//一定要记得初始化,坑爹cf
    for(int i=0;i<l-1;i++)
    {
    	int a=s[i]-'0';
    	int b=s[i+1]-'0';
    	if(dis[a][b]==inf)//如果不能到达,直接输出-1啦
    	return -1;
    	else
    	ans+=dis[a][b]-1;//因为我们统计的是需要插入的数字数量,所以就为步数-1
    }
    return ans;
}

int main()
{
   scanf("%s",s);
   for(int i=0;i<=9;i++)
   {
    for(int j=0;j<=9;j++)  
    { 
      printf("%d ",fun(i,j));//每次直接输出啦
    }
    printf("\n");
   }
   return 0;
}

你可能感兴趣的:(CF整理题)