游游的整数翻转
思路
倒过来输出前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;
}

京公网安备 11010502036488号