本文主要是介绍[USAO training题]Combination Lock,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Combination Lockhttps://train.usaco.org/usacoprob2?a=bWHoWMsO5Pi&S=combo
农夫约翰的奶牛不停地从他的农场中逃出来,导致了很多损害。为了防止它们再逃出来,他买了一只很大的号码锁以防止奶牛们打开牧场的门。
农夫约翰知道他的奶牛很聪明,所以他希望确保它们不会在简单地试了很多不同的号码组合之后就能轻易开锁。锁上有三个转盘,每个上面有数字1..N (1 <= N <= 100),因为转盘是圆的,所以1和N是相邻的。有两种能开锁的号码组合,一种是农夫约翰设定的,还有一种“预设”号码组合是锁匠设定的。但是,锁有一定的容错性,所以,在每个转盘上的数字都与一个合法的号码组合中相应的数字相距两个位置以内时,锁也会打开。
比如说,如果农夫约翰的号码组合是(1,2,3),预设号码组合是(4,5,6),在转盘被设定为(1,N,5)(因为这和农夫约翰的号码组合足够接近)或(2,4,8)(因为这和预设号码组合足够接近)。注意,(1,5,6)并不会打开锁,因为它与任一号码组合都不够接近。 给出农夫约翰的号码组合和预设号码组合,请计算能够开锁的不同的号码组合的数目。号码是有序的,所以(1,2,3)与(3,2,1)不同。
INPUT FORMAT
第一行:整数N。
第二行:三个以空格分隔的整数,为农夫约翰的号码组合。
第三行:三个以空格分隔的整数,为预设号码组合(可能与农夫约翰的号码组合相同)。
SAMPLE INPUT (file comb.in)
50
1 2 3
4 5 6
OUTPUT FORMAT
第一行:所有不同的能够开锁的号码组合的总数。
SAMPLE OUTPUT (file comb.out)
249
(翻译转载自https://blog.csdn.net/finded/article/details/39999241)
这道题思路其实非常简单:
先找出两个密码各个位数上的有效数字:在1——n中找到可以和当前数字有效匹配的5个数字(n-2,n-1,n,n+1,n+2)要注意,如果数字是n,n-1,或者1,2的情况要另外判断。
#include<bits/stdc++.h>
using namespace std;
int n;
int a1,a2,a3,b1,b2,b3;
int a11[5],a22[5],a33[5],b11[5],b22[5],b33[5];//每一位数字都给一个相应的数组范围存储有效数字
void range(int q[5],int num)
{if(num==1)//如果数字为1{q[0]=n-1;q[1]=n;q[2]=2;q[3]=3;q[4]=num;}else if(num==2)//如果数字为2{q[0]=n;q[1]=1;q[2]=3;q[3]=4;q[4]=num;}else if(num==n)//如果数字为n{q[0]=n-1;q[1]=n-2;q[2]=1;q[3]=2;q[4]=num;}else if(num==n-1)//如果数字为n-1{q[0]=n-2;q[1]=n-3;q[2]=n;q[3]=1;q[4]=num;}else//正常计算{q[0]=num-2;q[1]=num-1;q[2]=num+1;q[3]=num+2;q[4]=num;}
}
在每一个数字的有效数字都确定好之后,先遍历在1——n数字的所有可能。
int main()
{freopen("combo.in","r",stdin);freopen("combo.out","w",stdout);cin>>n>>a1>>a2>>a3>>b1>>b2>>b3;range(a11,a1);range(a22,a2);range(a33,a3);range(b11,b1);range(b22,b2);range(b33,b3);int ans=0;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){for(int k=1;k<=n;k++){if(check1(i,j,k)||check2(i,j,k)){ans++;}}}}cout<<ans<<endl;return 0;
}
分别判断和两个密码的匹配情况。只要有一种匹配上了,那这个密码就是一个有效密码,ans+1.
两个判断代码十分简单,如下:
int check1(int i,int j,int k)
{for(int z=0;z<5;z++){if(i==a11[z]){break;}if(z==4){return 0;}}for(int z=0;z<5;z++){if(j==a22[z]){break;}if(z==4){return 0;}}for(int z=0;z<5;z++){if(k==a33[z]){break;}if(z==4){return 0;}}return 1;
}
int check2(int i,int j,int k)
{for(int z=0;z<5;z++){if(i==b11[z]){break;}if(z==4){return 0;}}for(int z=0;z<5;z++){if(j==b22[z]){break;}if(z==4){return 0;}}for(int z=0;z<5;z++){if(k==b33[z]){break;}if(z==4){return 0;}}return 1;
}
最后放上全代码,记得点个赞捏╮( ̄▽ ̄)╭
(文件名为combo,记得看题目描述)
/*
ID:s.randy1
PROG:combo
LANG:C++
*/
#include<bits/stdc++.h>
using namespace std;
int n;
int a1,a2,a3,b1,b2,b3;
int a11[5],a22[5],a33[5],b11[5],b22[5],b33[5];//每一位数字都给一个相应的数组范围存储有效数字
void range(int q[5],int num)
{if(num==1)//如果数字为1{q[0]=n-1;q[1]=n;q[2]=2;q[3]=3;q[4]=num;}else if(num==2)//如果数字为2{q[0]=n;q[1]=1;q[2]=3;q[3]=4;q[4]=num;}else if(num==n)//如果数字为n{q[0]=n-1;q[1]=n-2;q[2]=1;q[3]=2;q[4]=num;}else if(num==n-1)//如果数字为n-1{q[0]=n-2;q[1]=n-3;q[2]=n;q[3]=1;q[4]=num;}else//正常计算{q[0]=num-2;q[1]=num-1;q[2]=num+1;q[3]=num+2;q[4]=num;}
}
int check1(int i,int j,int k)
{for(int z=0;z<5;z++){if(i==a11[z]){break;}if(z==4){return 0;}}for(int z=0;z<5;z++){if(j==a22[z]){break;}if(z==4){return 0;}}for(int z=0;z<5;z++){if(k==a33[z]){break;}if(z==4){return 0;}}return 1;
}
int check2(int i,int j,int k)
{for(int z=0;z<5;z++){if(i==b11[z]){break;}if(z==4){return 0;}}for(int z=0;z<5;z++){if(j==b22[z]){break;}if(z==4){return 0;}}for(int z=0;z<5;z++){if(k==b33[z]){break;}if(z==4){return 0;}}return 1;
}
int main()
{freopen("combo.in","r",stdin);freopen("combo.out","w",stdout);cin>>n>>a1>>a2>>a3>>b1>>b2>>b3;range(a11,a1);range(a22,a2);range(a33,a3);range(b11,b1);range(b22,b2);range(b33,b3);int ans=0;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){for(int k=1;k<=n;k++){if(check1(i,j,k)||check2(i,j,k)){ans++;}}}}cout<<ans<<endl;return 0;
}
这篇关于[USAO training题]Combination Lock的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!