2147: Digit

2024-03-27 05:08
文章标签 digit 2147

本文主要是介绍2147: Digit,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

看到题目首先想到了数位dp

观察发现,从低位向高位很好推.

令fijkg表示第i个位置,进位值为j 数位和为k 乘d后数位和为g得情况是否成立...

稍微算一算100 * 10 * 1000 * 1000肯定爆掉了...

考虑优化,令fijk表示能凑成进位值为i 数位和为j 乘d后数位和为k最短得长度...

那么这样复杂度就在1000w 可以接受...

因为要保证得到得数是最小得情况,那么只能从高位到低位枚举。

而且每次选出来的值均对原本乘积和得值有影响,那么还要更新一下...

理论上来说不是很难,但是本沙茶还是写了一天...

c++代码如下:

#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <cstring>
#include <iostream>
#include <algorithm>
#define debug(x) cout<<#x<<" = "<<x<<endl;
#define lowbit(x) x&(-x)
#define PA pair<int, int>
#define MK make_pair
#define rep(i,x,y) for(register int i = x; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x; i >= y; -- i)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T&x)
{x = 0;char c;int sign = 1;do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));x *= sign;
}int n,s1,s2,d;
int f[10][901][910],nw[101],t[101];
struct Str { int lst,num1,num2; };inline void bfs()
{queue<Str>q; q.push((Str){0,0,0});f[0][0][0] = 0;while(!q.empty()){Str a = q.front();q.pop();rep(i,0,9) if(a.num1 + i <= s1 && a.num2 + (i*d + a.lst)%10 <= s2 && f[(a.lst + i*d)/10][a.num1 + i][a.num2 + (i*d + a.lst)%10] > f[a.lst][a.num1][a.num2] + 1){f[(a.lst + i*d)/10][a.num1 + i][a.num2 + (i*d + a.lst)%10] = f[a.lst][a.num1][a.num2] + 1; q.push((Str){(a.lst + i*d)/10,a.num1 + i,a.num2 + (i*d + a.lst)%10});}}
}
void get(int now,int s1,int p)
{if(now == n + 1) exit(0);rep(k,0,9){rep(j,0,9){int q = now,z = p;t[now] = k*d + j;while(t[q] + nw[q] >= 10){t[q - 1] = (t[q] + nw[q]) / 10;t[q] = (t[q] + nw[q]) %10;z += t[q] - nw[q];--q;}z += t[q];if(s1 >= k && s2 >= z && f[j][s1 - k][s2 - z] + now <= n){q = now;nw[q] = k*d; p += nw[q]; while(nw[q] >= 10){p -= nw[q - 1] + nw[q];nw[q - 1] += nw[q]/10;nw[q] %= 10;p += nw[q - 1] + nw[q];--q;}printf("%d",k);get(now + 1,s1 - k,p);}}}
}
int main()
{memset(f,0x3f,sizeof f);read(n);read(s1);read(s2);read(d);bfs();int z = 0;rep(i,1,9){rep(j,0,9)if(s1 >= i && s2 - (i*d + j)%10 - (i*d + j)/10 >= 0 && f[j][s1 - i][s2 - (i*d + j)%10 - (i*d + j)/10] < n){z = i;nw[1] = (i * d)%10;nw[0] = (i * d)/10;break;}if(z) break;}if(!z) return puts("-1");cout << z;get(2,s1 - z,nw[1] + nw[0]);return 0;
}

这篇关于2147: Digit的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851034

相关文章

Kaggle竞赛——手写数字识别(Digit Recognizer)

目录 1. 数据集介绍2. 数据分析3. 数据处理与封装3.1 数据集划分3.2 将数据转为tensor张量3.3 数据封装 4. 模型训练4.1 定义功能函数4.1 resnet18模型4.3 CNN模型4.4 FCNN模型 5. 结果分析5.1 混淆矩阵5.2 查看错误分类的样本 6. 加载最佳模型7. 参考文献 本次手写数字识别使用了resnet18(比resnet50精度更

leetcode 902. Numbers At Most N Given Digit Set

题目链接 Given an array of digits which is sorted in non-decreasing order. You can write numbers using each digits[i] as many times as we want. For example, if digits = ['1','3','5'], we may write number

hdu 2147

#include <stdio.h>int main(){int n,m;while(scanf("%d%d",&n,&m) && n+m){if((n*m)%2==0) printf("Wonderful!\n");else printf("What a pity!\n");}}

Leetcode181:Number of Digit One

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n. For example: Given n = 13, Return 6, because digit 1 occurred in the followin

HDU 2147 kiki's game 博弈

我已经分不出来这是不是博弈了,反正我是没想到,看了别人的博客,我只想说给人类的智商跪了。。。。。。。。竟然是倒着推出来的 步骤1:将所有终结位置标记为必败点(P点); 步骤2: 将所有一步操作能进入必败点(P点)的位置标记为必胜点(N点) 步骤3:如果从某个点开始的所有一步操作都只能进入必胜点(N点) ,则将该点标记为必败点(P点) ; 步骤4: 如果在步骤3未能找到新的必败(P点),则算法终止

(LeetCode)Nth Digit --- 第几位数字

Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... Note: n is positive and will fit within the range of a 32-bit signed integer (n < 231).

【规律题】Backward Digit Sums

【POJ3187】【洛谷1118】Backward Digit Sums Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Problem Description FJ and his cows enjoy playing a mental game. They write do

HDU Specialized Four_Digit Numbers

题目传送门: http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid=1&sectionid=2&problemid=24 本题核心是基本功是进制转换,分解方法是除模取余法,写三个函数比较清晰。 #include<stdio.h>using namespace std;//HDU Specialized Four_Digit

wikioi 2147 bitset+map解决

题目描述 Description 小明是一名天文爱好者,他喜欢晚上看星星。这天,他从淘宝上买下来了一个高级望远镜。他十分开心,于是他晚上去操场上看星星。 不同的星星发出不同的光,他的望远镜可以计算出观测到的星星发出的光的数值W。小明当然想尽可能地多看到星星,于是他每看到一颗星星,就要看看他之前有没有看过这颗星星。但是他看的星星太多了,他根本数不过来,于是他让你帮忙。

LeetCode-400. Nth Digit

问题:https://leetcode.com/problems/nth-digit/?tab=Description Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, **分析:**S1=1 S2=12 S3=123 S4=1234 … S9=123456789 S10