您的位置:首页 > 理论基础

AtCoder Beginner Contest 085 C Otoshidama(计算机整数乘法问题+方程求解)

2018-01-09 15:04 429 查看
Problem Statement
The commonly used bills in Japan are 10000-yen, 5000-yen and 1000-yen bills. Below, the word "bill" refers to only these.

According to Aohashi, he received an otoshidama (New Year money gift) envelope from his grandfather that contained N bills for a total of Y yen, but he may be lying. Determine whether such a situation is possible, and if it is, find a possible set of bills contained in the envelope. Assume that his grandfather is rich enough, and the envelope was large enough.

Constraints
1≤N≤2000
1000≤Y≤2×107
N is an integer.
Y is a multiple of 1000.
Input
Input is given from Standard Input in the following format:

N Y
Output
If the total value of N bills cannot be Y yen, print -1 -1 -1.

If the total value of N bills can be Y yen, let one such set of bills be "x 10000-yen bills, y 5000-yen bills and z 1000-yen bills", and print x, y, z with spaces in between. If there are multiple possibilities, any of them may be printed.

Sample Input 1
Copy
9 45000
Sample Output 1
Copy
4 0 5
If the envelope contained 4 10000-yen bills and 5 1000-yen bills, he had 9 bills and 45000 yen in total. It is also possible that the envelope contained 9 5000-yen bills, so the output 0 9 0 is also correct.

Sample Input 2

20 196000
Sample Output 2

-1 -1 -1
When the envelope contained 20 bills in total, the total value would be 200000 yen if all the bills were 10000-yen bills, and would be at most 195000 yen otherwise, so it would never be 196000 yen.

Sample Input 3

1000 1234000
Sample Output 3
14 27 959
There are also many other possibilities.

Sample Input 4

2000 20000000
Sample Output 4

2000 0 0
题意:类似百马百担,纸币有10000元 5000元 1000元 给出n张 y元,求出一种可以达成上述条件的3种纸币的张数即可。

思路:暴力循环即可
1.三重循环(这是最傻也是最耗时的循环)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <cstring>
#include <cmath>
#include <map>
#include <stack>
#define N 1005
using namespace std;
typedef long long ll;
int main()
{
int n,y;
scanf("%d%d",&n,&y);
int a=1000,b=5000,c=10000;
int s1=-1,s2=-1,s3=-1,n1,n2,n3;
if(n*1000>y||n*10000<y)
s1=-1,s2=-1,s3=-1;
else
{
n3=y/c;
for(int i=n3; i>=0; i--)
{
int flag=0;
n2=(y-i*10000)/5000;
for(int j=n2; j>=0; j--)
{

n1=(y-i*10000-j*5000)/1000;
for(int k=n1; k>=0; k--)
{

if(i+j+k==n&&i*c+j*b+k*a==y)
{
s1=k,s2=j,s3=i;
flag=1;
break;
}
}
if(flag)
break;

}
if(flag)
break;
}
}
printf("%d %d %d\n",s3,s2,s1);

}2.二重循环
(在三重循环的基础上仅仅改变了最后一重循环,因为仔细观察最后一重循环完全是多余的,直接判断即可,但是由于个人对计算机乘法运算不敏感,所以。。。。)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <cstring>
#include <cmath>
#include <map>
#include <stack>
#define N 1005
using namespace std;
typedef long long ll;
int main()
{
int n,y;
scanf("%d%d",&n,&y);
int a=1000,b=5000,c=10000;
int s1=-1,s2=-1,s3=-1,n1,n2,n3;
if(n*1000>y||n*10000<y)
s1=-1,s2=-1,s3=-1;
else
{
n3=y/c;
for(int i=n3; i>=0; i--)
{
int flag=0;
n2=(y-i*10000)/5000;
for(int j=n2; j>=0; j--)
{

n1=(y-i*10000-j*5000)/1000;
if(i+j+n1==n&&i*c+j*b+n1*a==y)
{
s1=n1,s2=j,s3=i;
flag=1;
break;
}

}
if(flag)
break;
}
}
printf("%d %d %d\n",s3,s2,s1);

}3.一重循环:
2个三元一次方程,消掉一个未知数,仅剩2个未知数,一个循环,另一个利用乘法规则求解
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <cstring>
#include <cmath>
#include <map>
#include <stack>
#define N 1005
using namespace std;
typedef long long ll;

int main()
{
int n,y;
while(scanf("%d%d",&n,&y)==2){
int a=y/10000,s1=-1,s2=-1,s3=-1;
for(int i=a;i>=0;i--){
int j=(y-1000*n-9000*i)/4000;
if(i*9000+4000*j==y-1000*n&&i+j<=n&&i>=0&&j>=0)
{
s1=i,s2=j,s3=n-i-j;
break;
}
}
printf("%d %d %d\n",s1,s2,s3);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐