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;elsecout << "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;
}