一开始看到这道题目的时候,感觉好难
还要算出罗马的规则。
但是仔细一看,数据规模很小, n 只给到3500
看完题目给出了几组样例之后就有感觉了
解题方法就是:
n的每个十进制数 转换成相应的罗马数字,然后统计每个罗马数字出现的次数即可
还是一道简单的构造题。
(以下摘自https://www.byvoid.com/blog/usaco-221preface-numbering/)
转化有以下规则:
1、数较大部分在前,较小部分在后
2、表示10整倍数的字母(I X C M)最多可以累加三次
3、要累加4次的数应该将比该数的字母稍大的表示5整倍数或是10的整倍数的字母在后,累加的字母在前(例如IV XL CD CM)
了解以上规则后发现并不需要实际“转化”出罗马数字,而只用统计每个字母出现的次数。
My Source Code:
/* ID: wushuai2 PROG: preface LANG: C++ */ //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <fstream> #include <cstring> #include <cmath> #include <stack> #include <string> #include <map> #include <set> #include <list> #include <queue> #include <vector> #include <algorithm> #define Max(a,b) (((a) > (b)) ? (a) : (b)) #define Min(a,b) (((a) < (b)) ? (a) : (b)) #define Abs(x) (((x) > 0) ? (x) : (-(x))) #define MOD 1000000007 #define pi acos(-1.0) using namespace std; typedef long long ll ; typedef unsigned long long ull ; typedef unsigned int uint ; typedef unsigned char uchar ; template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;} template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;} const double eps = 1e-7 ; const int M = 660000 ; const ll P = 10000000097ll ; const int INF = 0x3f3f3f3f ; const int MAX_N = 20 ; const int MAXSIZE = 101000000; int N, ans[10]; string op[5][10] = { {}, {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}, {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}, {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}, {"", "M", "MM", "MMM"} }; void add(string str){ int i, j; for(i = 0; i < str.length(); ++i){ if(str[i] == 'I') ++ans[1]; else if(str[i] == 'V') ++ans[2]; else if(str[i] == 'X') ++ans[3]; else if(str[i] == 'L') ++ans[4]; else if(str[i] == 'C') ++ans[5]; else if(str[i] == 'D') ++ans[6]; else if(str[i] == 'M') ++ans[7]; } } int main() { ofstream fout ("preface.out"); ifstream fin ("preface.in"); int i, j, k, t, n, s, c, w, q; fin >> N; for(i = 1; i <= N; ++i){ int temp_g = i % 10; string temp = op[1][temp_g]; add(temp); if(i < 10) continue; int temp_s = (i / 10) % 10; temp = op[2][temp_s]; add(temp); if(i < 100) continue; int temp_b = (i / 100) % 10; temp = op[3][temp_b]; add(temp); if(i < 1000) continue; int temp_q = i / 1000; temp = op[4][temp_q]; add(temp); } int flag = -1; for(i = 7; i >= 1; --i){ if(ans[i]){ flag = i; break; } } for(i = 1; i <= flag; ++i){ if(i == 1){ fout << "I" << ' ' << ans[i] << endl; } else if(i == 2){ fout << "V" << ' ' << ans[i] << endl; } else if(i == 3){ fout << "X" << ' ' << ans[i] << endl; } else if(i == 4){ fout << "L" << ' ' << ans[i] << endl; } else if(i == 5){ fout << "C" << ' ' << ans[i] << endl; } else if(i == 6){ fout << "D" << ' ' << ans[i] << endl; } else if(i == 7){ fout << "M" << ' ' << ans[i] << endl; } } fin.close(); fout.close(); return 0; }