http://train.usaco.org/usacoprob2?a=2O4pW4JgSuc&S=preface
智障了数次之后终于A了。。思路没什么问题,就是一些小地方没注意,debug了很久,喜极而泣
下次看到提示溢出的,一定要仔细找。看了半个小时想了各种原因,最后发现是下面的循环次数太多超过开的数组单元的数量。
刚开始拿到题很懵逼。后来百度了罗马数字表,结合题意,发现只用找出1-9,10(+10)-90;100(+100)-900;1000(+1000)-4000;这几个就好了,因为知道了它们中的字母,其余所有的数字都可用这些数字的和表示,就很容易知道其他数字中各个字母的数量。
第一次尝试用map,感觉还行。要注意设定map映射的时候一定要在main函数里面设定。
还有要注意if后面的括号里写条件的时候一定要搞清运算符优先级!再次调了半小时。。(搞不清也没关系,拼命加括号
总之是一道带点巧妙的暴力。
代码如下。傻逼的地方都标注出来了。
LANG:C++
TASK:preface
*/
#include <stdio.h>
#include <iostream>
#include <bitset>
#include <algorithm>
#include <map>
using namespace std;
int mark[4008][7];//对应4008个数字中,7个字母的数量分别是多少。
map<int,int> numbers; //字母表示的数字对应数组下标
map<int,char> numbe; //数组下标对应字母
int amount[7];
void init(){//处理好已知数字中的字母含量
mark[1][0] = 1;
mark[5][1] = 1;
mark[10][2] = 1;
mark[50][3] = 1;
mark[100][4] = 1;
mark[500][5] = 1;
mark[1000][6] = 1;
}
void judge(int base,int num){//base:1,10,100,1000...
int status;
status = num/base;//此处直接除就好。。还有位数为1的时候不用单独考虑,把base设置成0更是数死早。。
int k = numbers[base];
int j = numbers[base*5];
if(status<=3){
// cout<<mark[num][k]<<" "<<num<<endl;
mark[num][k] = status;
// if(num==20) cout<<mark[num][k]<<endl;
}
else if(status==4){
mark[num][k] = 1;
mark[num][j] = 1;
}
else if(status==5)
mark[num][j] = 1;
else if(status<=8){
int shu = status%5;
mark[num][j] = 1;
mark[num][k] = shu;
}
else{
mark[num][k] = 1;
j = numbers[base*10];
mark[num][j] = 1;
}
}
void add(int n1,int n2,int n3){
for(int i = 0;i<7;i++){
<span style="white-space:pre"> </span>mark[n3][i] = mark[n2][i] + mark[n1][i];
}
}
int main(){
freopen("preface.in","r",stdin);
freopen("preface.out","w",stdout);
init();
int n;
scanf("%d",&n);
numbers[1] = 0;
numbers[5] = 1;
numbers[10] = 2;
numbers[50] = 3;
numbers[100] = 4;
numbers[500] = 5;
numbers[1000] = 6;
numbe[0] = 'I';
numbe[1] = 'V';
numbe[2] = 'X';
numbe[3] = 'L';
numbe[4] = 'C';
numbe[5] = 'D';
numbe[6] = 'M';
int n1,n2;
for(int i = 1;i<10;i++)
judge(1,i);
for(int i = 10;i<100;i++){
if(!(i%10))
judge(10,i);
else{
n1 = i%10;
n2 = i - n1;
add(n1,n2,i);
}
}
for(int i = 100;i<1000;i++){
if(!(i%100))
judge(100,i);
else{
n1 = i%100;
n2 = i - n1;
add(n1,n2,i);
}
}
for(int i = 1000;i<4000;i++){
if(!(i%1000))
judge(1000,i);
else{
n1 = i%1000;
n2 = i - n1;
add(n1,n2,i);
}
}
for(int i = 1;i<=n;i++){
for(int j = 0;j<7;j++){
//printf("%d",mark[i][j]);
amount[j] += mark[i][j];
}
}
// cout<<mark[1000][4]<<" "<<1000<<endl;
for(int i = 0;i<7;i++){
if(amount[i])
printf("%c %d\n",numbe[i],amount[i]);
}
return 0;
}