游游的整数翻转
思路
倒过来输出前k位,然后再正着输出k位之后的数字。
设置一个变量
来表示是否遇到过非
数字,如果遇到过则可以直接输出当前遍历的数字,否则就不输出,这样可以不输出前导零。不过如果数字为
则需要特判输出。
复杂度为
代码实现
#include <bits/stdc++.h> using namespace std; int main() { string t; int k; cin>>t>>k; int flag = 0; for(int i=k-1;i>=0;i--){ if(t[i]!='0') flag = 1; if(flag) cout<<t[i]; } for(int i=k;t[i];i++){ if(t[i]!='0') flag = 1; if(flag) cout<<t[i]; } if(!flag) cout<<0; }
游游的排列统计
思路
复杂度为
代码实现
#include <bits/stdc++.h> using namespace std; int n; int cnt; int op[100]; int st[100]; //判断素数 int isprime(int x) { if(x<=2) return x==2; for(int i=2;i<=x/i;i++){ if(x%i==0) return 0; } return 1; } void dfs(int u) { if(u>n){ for(int i=1;i<n;i++){ int x = op[i] + op[i+1]; //如果相邻和为素数则不满足条件,直接return if(isprime(x)) return; } cnt++; return; } for(int i=1;i<=n;i++){ if(!st[i]){ op[u] = i; st[i] = 1; dfs(u+1); st[i] = 0; } } } int main() { cin>>n; dfs(1); cout<<cnt; }
游游刷题
思路
将所有的数对
取模。
如果对
取模后为
,则直接为
的倍数,直接占据一天。
否则,如果对
取模为
,那么需要找对
取模为
的数值搭配才能为
的倍数。
设
为对
取模为
的数的数量,其能对答案产生的贡献为
,(要注意统计了
后不需要再统计
的贡献)
特判:如果
,那么此时的贡献为
。
时间复杂度为
代码实现
#include <bits/stdc++.h> using namespace std; #define int long long int n,k; set<int>st; map<int,int>cnt; signed main() { cin>>n>>k; for(int i=1;i<=n;i++){ int x; cin>>x; cnt[x%k]++; } int ans = 0; for(auto it:cnt){ if(it.first==0) continue; if(st.count(it.first)) continue; int x1 = it.first,x2 = (k-x1)%k; if(!cnt.count(x2)) continue; st.insert(x1),st.insert(x2); // 防止重复统计 if(x1!=x2)ans += min(cnt[x1],cnt[x2]); else ans += cnt[x1]/2; } ans += cnt[0]; // 直接为k的倍数可以直接占据一天,贡献为cnt[0] cout<<ans; }
游游买商品
思路
感觉是类似背包然后分状态讨论的动态规划。
状态转移
时间复杂度为
,空间复杂度可以通过滚动数组优化到
代码实现
#include <bits/stdc++.h> using namespace std; const int N = 2e3+5; #define int long long int n,m; int a[N],b[N]; int f[N][N][3]; // f[i][j][0] = f[i-1][j][0/1/2] // f[i][j][1] = f[i-1][j-ai][0/1/2] + bi // f[i][j][2] = f[i-1][j-ai/2][1] + bi signed main() { cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) cin>>b[i]; for(int i=0;i<=m;i++){ f[0][i][0] = f[0][i][1] = -1e18; } f[0][0][0] = 0; for(int i=1;i<=n;i++){ for(int j=0;j<=m;j++){ f[i][j][0] = max(max(0ll,f[i-1][j][0]),max(f[i-1][j][1],f[i-1][j][2])); f[i][j][1] = -1e18; if(j>=a[i]){ f[i][j][1] = max(f[i-1][j-a[i]][0],max(f[i-1][j-a[i]][1],f[i-1][j-a[i]][2])) + b[i]; } f[i][j][2] = -1e18; if(j>=a[i]/2){ f[i][j][2] = f[i-1][j-a[i]/2][1] + b[i]; } } } int ans = max(f[n][m][0],max(f[n][m][1],f[n][m][2])); cout<<ans; }
//滚动数组优化 #include <bits/stdc++.h> using namespace std; const int N = 2e3+5; #define int long long int n,m; int a[N],b[N],f[N][3]; signed main() { cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) cin>>b[i]; int ans = 0; for(int i=0;i<=m;i++){ f[i][0] = f[i][1] = f[i][2] = -1e18; } f[0][0] = 0; for(int i=1;i<=n;i++){ for(int j=m;j>=0;j--){ f[j][0] = max(f[j][0],max(f[j][1],f[j][2])); f[j][1] = -1e18; if(j>=a[i]){ f[j][1] = max(f[j-a[i]][0], max(f[j-a[i]][1],f[j-a[i]][2])) + b[i]; } f[j][2] = -1e18; if(j>=a[i]/2){ f[j][2] = f[j-a[i]/2][1] + b[i]; } ans = max(max(ans,f[j][0]),max(f[j][1],f[j][2])); } } cout<<ans; }