NOIP 2017题解(更新ing)
2017-12-07 23:20
323 查看
D1T1:小凯的疑惑
题目:求一个最大的正整数c,使得ax+by=c(其中a,b为互质的两个正整数)没有非负正整数解。
正解:(想要直接数学推导的就去找数竞大佬吧。。。下面说说考试时怎么办——“一猜想+两验证”)
①打表找规律(不急,后面有严格证明)
![](http://img.blog.csdn.net/20171207225443677?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvS0dWMDkz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
观察不为-1的所有元素可不完全归纳所求最大的c即ab-a-b。
下面是赛后打表验证的代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll exgcd(ll a,ll b,ll &x,ll &y) {
if (!b) {
x=1,y=0;
return a;
}
ll d=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return d;
}
inline bool judge(ll a,ll b,ll c) {
ll x,y,d=exgcd(a,b,x,y);
if (c%d) return false;
x*=c/d,y*=c/d;
ll tmp=b/d;
x=(x%tmp+tmp)%tmp;
y=(c-a*x)/b;
return y>=0&&x>=0;
}
inline ll gcd(ll a,ll b) {
return !b?a:gcd(b,a%b);
}
int main() {
for (int i=1;i<=10;++i) {
for (int j=1;j<=10;++j) {
if (i==1||j==1||gcd(i,j)>1) {
printf("%-3d ",-1);
continue;
}
else {
for (int t=1000;t;--t)
if (!judge(i,j,t)&&t) {
printf("%-3d ",t);
break;
}
}
}
puts("");
}
return 0;
}②证明c=ab-a-b原方程没有有非负正整数解:
假设有非负正整数解:
令ax+by=ab-a-b
得x=b-1-(1+y)b/a
已知a,b互质,所以a|b不成立,又因为x为正整数所以a|(1+y)
设y+1=ka(k≥1),x=b-1-kb=(1-k)b-1,因为k≥1,所以x<0,与假设矛盾。
所以假设不成立,c=ab-a-b原方程没有非负正整数解。
③证明ab-a-b是最大的c使原方程没有非负整数解:
假设它不是,设ax+by=ab-a-b+t(t为正整数)。
设t=ap+bq,其中p,q为整数(此处不要求为正)
根据exgcd算法的性质(这一点理解后面就容易了):设d=gcd(a,b),由于通解为x=x0+k*(b/d),y=y0+k*(a/d)),所以一定存在一组解(x,y)其中y>0且-b<x≤0
此处ap+bq=t(a,b互质肯定有解),令q>0且-b<p≤0。
现在观察原方程ax+by=ab-a-b+t=(b-1+p)a+(q-1)b,
因为q>0且-b<p≤0,所以b-1+p≥0且q-1≥0。
所以x=b-1+p,y=q-1即为原方程的一组非负整数解,无论t多大都成立。
证毕,下面给出正解代码(自嘲而已)。
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
ll a,b;
int main() {
// freopen("math.in","r",stdin);
// freopen("math.out","w",stdout);
cin>>a>>b;
cout<<a*b-a-b<<endl;
return 0;
}
(持续更新ing)
题目:求一个最大的正整数c,使得ax+by=c(其中a,b为互质的两个正整数)没有非负正整数解。
正解:(想要直接数学推导的就去找数竞大佬吧。。。下面说说考试时怎么办——“一猜想+两验证”)
①打表找规律(不急,后面有严格证明)
观察不为-1的所有元素可不完全归纳所求最大的c即ab-a-b。
下面是赛后打表验证的代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll exgcd(ll a,ll b,ll &x,ll &y) {
if (!b) {
x=1,y=0;
return a;
}
ll d=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return d;
}
inline bool judge(ll a,ll b,ll c) {
ll x,y,d=exgcd(a,b,x,y);
if (c%d) return false;
x*=c/d,y*=c/d;
ll tmp=b/d;
x=(x%tmp+tmp)%tmp;
y=(c-a*x)/b;
return y>=0&&x>=0;
}
inline ll gcd(ll a,ll b) {
return !b?a:gcd(b,a%b);
}
int main() {
for (int i=1;i<=10;++i) {
for (int j=1;j<=10;++j) {
if (i==1||j==1||gcd(i,j)>1) {
printf("%-3d ",-1);
continue;
}
else {
for (int t=1000;t;--t)
if (!judge(i,j,t)&&t) {
printf("%-3d ",t);
break;
}
}
}
puts("");
}
return 0;
}②证明c=ab-a-b原方程没有有非负正整数解:
假设有非负正整数解:
令ax+by=ab-a-b
得x=b-1-(1+y)b/a
已知a,b互质,所以a|b不成立,又因为x为正整数所以a|(1+y)
设y+1=ka(k≥1),x=b-1-kb=(1-k)b-1,因为k≥1,所以x<0,与假设矛盾。
所以假设不成立,c=ab-a-b原方程没有非负正整数解。
③证明ab-a-b是最大的c使原方程没有非负整数解:
假设它不是,设ax+by=ab-a-b+t(t为正整数)。
设t=ap+bq,其中p,q为整数(此处不要求为正)
根据exgcd算法的性质(这一点理解后面就容易了):设d=gcd(a,b),由于通解为x=x0+k*(b/d),y=y0+k*(a/d)),所以一定存在一组解(x,y)其中y>0且-b<x≤0
此处ap+bq=t(a,b互质肯定有解),令q>0且-b<p≤0。
现在观察原方程ax+by=ab-a-b+t=(b-1+p)a+(q-1)b,
因为q>0且-b<p≤0,所以b-1+p≥0且q-1≥0。
所以x=b-1+p,y=q-1即为原方程的一组非负整数解,无论t多大都成立。
证毕,下面给出正解代码(自嘲而已)。
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
ll a,b;
int main() {
// freopen("math.in","r",stdin);
// freopen("math.out","w",stdout);
cin>>a>>b;
cout<<a*b-a-b<<endl;
return 0;
}
(持续更新ing)
相关文章推荐
- NOIP2017 冬游记--浅谈划水一年欢乐爆0(实时更新)
- 计蒜客 2017 NOIP 提高组模拟赛(一)题解
- NOIP 2017 Day2 题解?
- [题解]NOIP2017 Day2 Solution - by xyz32768
- LUOGU P3954题解(NOIP 2017普及组第一题)
- NOIP2017提高组初赛 个人理解+题解
- LUOGU P3955题解(NOIP 2017第二题)
- 【提高组NOIP2017】时间复杂度 题解 分治系统处理
- NOIP2017提高组初赛题解
- [题解]NOIP2017 Day1 Solution - by xyz32768
- [置顶] NOIP 模板整理计划 NOIP2017 RP++(持续更新中~)
- NOIP2017 逛公园 题解报告 【最短路 + 拓扑序 + dp】
- NOIP2017普及组复赛题解
- 2017-2018-2 1723《程序设计与数据结构》问题汇总(更新ing)
- NOIP2017 逛公园 题解报告 【最短路 + 拓扑序 + dp】
- {题解}[jzoj4924]【NOIP2017提高组模拟12.17】向再见说再见
- 2017NOIP总结(待更新)
- NOIP2017 考前汇总
- JZOJ5184. 【NOIP2017提高组模拟6.29】Gift
- 【NOIP模拟题】【图论】2016.11.18 第二题 心 题解