A. GCD Sum
思路:
虽然,当个位是偶数,然后总体只有奇数个奇数时,
一定是大于1的
MyCode:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10,maxm=2e5+10,mod=1e9+7;
typedef long long int ll;
typedef unsigned long long ull;
inline void solve() {
ll n;
cin>>n;
for(ll x=n,y,sum;; ++x) {
sum=0;
y=x;
while(y) {
sum+=y%10;
y/=10;
}
if(__gcd(x,sum)>1) {
cout<<x<<'\n';
return;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin>>T;
while(T--) solve();
return 0;
} B. Box Fitting
思路:
考虑先放入大的,再放小的。
那么可以写个的暴力,但是因为物块的宽度是2的次幂,所以暴力的复杂度只要
MyCode:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10,maxm=2e5+10,mod=1e9+7;
typedef long long int ll;
typedef unsigned long long ull;
int a[21],pw[21];
inline void solve() {
int n,w,ans(0);
cin>>n>>w;
for(int i=1,x;i<=n;++i) {
cin>>x;
a[(int)log2(x)]+=1;
}
ll sum=w;
while(n) {
ans+=1;
for(int i=19;~i;--i) while(a[i]&&pw[i]<=sum) {
a[i]-=1;
n-=1;
sum-=pw[i];
}
sum=w;
}
cout<<ans<<'\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
pw[0]=1;
for(int i=1;i<=20;++i) pw[i]=pw[i-1]<<1;
int T;
cin>>T;
while(T--) solve();
return 0;
} C. Planar Reflections
看完题目就不用多想了,满足递归的性质,爆搜+记忆化去模拟
爆搜除了要注意记忆化搜索,还要避免多次访问同一个状态
MyCode:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10,maxm=2e5+10,mod=1e9+7;
typedef long long int ll;
typedef unsigned long long ull;
int n,k;
ll dp[1003][1003];
ll dfs(int i,int j) {
if(~dp[i][j]) return dp[i][j];
if(j==1||!i) return dp[i][j]=1;
ll ans(0);
return dp[i][j]=(dfs(k-i,j-1)+dfs(i-1,j))%mod;
}
inline void solve() {
cin>>k>>n;
memset(dp,-1,sizeof dp);
cout<<dfs(k,n)<<'\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin>>T;
while(T--) solve();
return 0;
} D. Bananas in a Microwave
输出每个数最早可以得到的回合,反之输出-1
思路:
就和筛一样的思路,假如第i回合是加法,表示当前是第i个回合j的状态,如果
,那么
要么在之前就得到了,要么在这个回合可以得到。乘法同理。
结果其实和第一维没有联系,可以滚动掉。
向上取整,尤其是乘法向上取整的处理
MyCode:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5,maxm=2e5+10,mod=1e9+7;
typedef long long int ll;
typedef unsigned long long ull;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n,m,op,y;
ll x;
cin>>n>>m;
vector<int>a(m+1,-1);
a[0]=0;
for(int i=1;i<=n;++i) {
cin>>op>>x>>y;
if(op&1) {
x=(x+maxn-1)/maxn;
for(int j=m;~j;--j) if(~a[j]) {
for(int t=1,k=x+j;t<=y&&k<=m&&a[k]==-1;++t,k+=x) a[k]=i;
}
}
else {
for(int j=m;~j;--j) if(~a[j]) {
ll k=(x*j+maxn-1)/maxn;
for(int t=1;t<=y&&k<=m&&a[k]==-1;++t,k=(x*k+maxn-1)/maxn) a[k]=i;
}
}
}
for(int i=1;i<=m;++i) cout << a[i] << " \n"[i == m];
return 0;
} E. Two Houses
大佬理解的意思:
从距离最大的两点开始问起。如果入度大的点都能到入度小的点,很容易构造出入度小的点到入度大的点的路径。
MyCode:
#include <bits/stdc++.h>
using namespace std;
const int maxn=507,maxm=2e5+10,mod=1e9+7;
typedef long long int ll;
typedef unsigned long long ull;
inline void solve() {
int n;
cin >> n;
int ar[n+1];
for(int i=1;i<=n;i++) cin >> ar[i];
vector<tuple<int,int,int> > edge;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(ar[i] > ar[j]) edge.emplace_back(ar[i]-ar[j],i,j);
else edge.emplace_back(ar[j]-ar[i],j,i);
}
}
sort(edge.rbegin(),edge.rend());
for(auto it : edge){
cout << "? " << get<1>(it) << " " << get<2>(it) << endl;
string s;
cin >> s;
if(s == "Yes"){
cout << "! " << get<1>(it) << " " << get<2>(it) << endl;
return;
}
}
cout << "! 0 0" << endl;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int T;
T=1;
// cin>>T;
while(T--) solve();
return 0;
} 
京公网安备 11010502036488号