B. I Hate 1111:题目
这题目太搞了呀,和dp感觉关系不大,数学题啊
首先要知道,11和111能构成后面所有的棍子数。
n = a*111+b*11;
最快做法
//算是规律?
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while (t--)
{
int n;
cin>>n;
int k = n/110;
int kk = n%11;
if (k<kk) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}
部分暴力
对于互质的m,n。x=a∗m+b∗n。a>=0,b>=0
其中不能构造的最大的数是n ∗ m − n − m
大于n ∗ m − n − m的数,都可以通过m和n构造出来。
所以最大数是1099,以下都可以暴力求。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> a((int)6e5);
vector<int> b((int)3e5), c((int)3e5);
int main()
{
int t;
cin >> t;
while (t--)
{
int n, ff = 0;
cin >> n;
if (n > 1099)
ff = 1;
else
{
for (int i = 0; i * 111 <= n; i++)
{
if ((n - i * 111) % 11 == 0)
{
ff = 1;
break;
}
}
}
if (ff)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
扩展欧几里得求得方程求解
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
void gcd(int a,int b,int &d,int &x,int &y)
{
if(!b)
{
d=a;
x=1;
y=0;
} else {
gcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int main()
{
int t;
cin>>t;
int d,x,y;
gcd(11,111,d,x,y);
while(t--)
{
int v;
cin>>v;
LL x0=x*v;
LL y0=y*v;
LL k=y0/11;
if(x0+k*111>=0)
{
cout<<"YES"<<endl;
} else {
cout<<"NO"<<endl;
}
}
return 0;
}
纯暴力好像也行?
#include<iostream>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int x;
cin >> x;
int flag = 0;
for (int i = 0; i < 11; i++)
{
if (x % 11 == 0)
{
flag = 1;
break;
}
x -= 111;
if (x < 0)break;
}
if (flag)cout << "YES" << endl;
else cout << "NO" << endl;
}
}
纯暴力确实行!
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--){
int x,flag=0;
scanf("%d",&x);
for(int i=0;i*111<=x;i++){
if((x-i*111)%11==0){
cout<<"YES"<<endl;
flag=1;
break;
}
}
if(!flag)
cout<<"NO"<<endl;
}
return 0;
}