USACO-1.3:Combination Lock

来源:互联网 发布:mysql注入 1#1 编辑:程序博客网 时间:2024/05/16 10:20

感觉有一年没有做ACM的题目了,以前熟悉的一些算法也都忘得差不多了。感觉就是大概知道自己以前会过。甚至已经有半年多没有真正地写代码了,就想着回头把USACO做完吧。突然着手编程,感觉有点吃力。这算是一个比较简单的题目,但是还是花了一个下午加一个上午的时间才搞定。
题目链接

题目大意:

一个农夫想锁住它的牛,设置了一个有三个数字的锁。牛要打开这个锁就能逃出去。给定一个数字N,锁上的每个数字可以是1~N。这些锁是环形的,因为锁不太准确,所以数字差两位以内也是可以打开锁的。比如N是50的话,其中一个数字锁设定的数字为1那么1, 2, 3, 50. 49都能打开这把锁。这把锁一开始设置了两个密码,一个是农夫设的,一个是锁匠设的。现在给你这个数字N和这两个密码,问你一共有几种情况牛可以打开锁出去。
比如N=50
农夫设的密码是123
锁匠设的密码是567
那么输出就是249,表示有249种组合可以打开这把锁。
注意,这个密码必须是接近其中一个人比如234,这个密码每个数字和农夫设置的密码都在2以内所以可以打开锁。456则是接近锁匠的密码可以打开这个锁。但是254这个密码不接近任何一个密码,因此不能打开这个锁。注意:它是循环的,所以49 50 1这个密码和农夫的也很接近,可以打开这把锁。

解题思路:

如果这个数字锁,小于或者等于5那么可以知道,任何的数字都是接近的(因为是循环的)。因此开锁的方法就是n*n*n种。
如果数字锁是大于5的,那么接近农夫和接近锁匠的数字组合分别都有125种,总共打开锁的组合就有250种。但是还要考虑其中重合的组合,比如上面的例子中345这个组合就是重合的,因此最后的答案是249种。所以,这道题我们就是需要计算它们重合的部分了。重合的部分很明显,就是这把锁三个数字分别重合的情况相乘。而每个数字的重合情况就是考虑它们之间的差。具体的参考一下代码应该就能明白了。

我的代码:

/*  ID:sunexio2  LANG:C++  TASK:combo */#include <iostream>#include <fstream>#include <cmath>using namespace std;ifstream fin("combo.in");ofstream fout("combo.out");int calRecom(int *a, int *b, int n){    int c[3] = {0, 0, 0};    for(int i = 0; i < 3; ++i){        int tmp = abs(a[i] - b[i]);        if(tmp > 4 && tmp < n - 4)            return 0;        if(tmp == 4)            c[i]++;        else if(tmp == 3)            c[i] += 2;        else if(tmp == 2)            c[i] += 3;        else if(tmp == 1)            c[i] += 4;        else if(tmp == 0)            c[i] += 5;        else if(tmp == n - 1)            c[i] += 4;        else if(tmp == n -2)            c[i] += 3;        else if(tmp == n - 3)            c[i] += 2;        else if(tmp == n - 4)            c[i]++;    }    return c[0] * c[1] * c[2];}int main(){    int n;    int fj_com[3], ms_com[3];    while(fin >> n){        for(int i = 0; i < 3; ++i)            fin >> fj_com[i];        for(int i = 0; i < 3; ++i)            fin >> ms_com[i];        if(n <= 5)            fout << n * n * n << endl;        else{            int res = 250;            int reCom = calRecom(fj_com, ms_com, n);            fout << res - reCom << endl;        }    }    return 0;}
0 0
原创粉丝点击