题意:懂得都懂
思路:直接记录有几个不高兴的,给他们互相换换即可
diamond:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=1e9 +7 ;
int fa[100005 ];
int n,m;
void solve () {
int ans=0 ;
int n;
cin>>n;
vector<int >g (n+1 );
for (int i = 1 ; i <=n ; ++i) {
cin>>g[i];
}
int p=0 ;
for (int i = 1 ; i <=n ; ++i) {
if (g[i]==i){
p++;
}
}
ans+=max ((p+1 )/2 ,(int )0 );
cout<<ans<<'\n' ;
}
signed main () {
ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 );
int t;
cin>>t;
while (t--){
solve ();
}
}
题意:问1-n中,最长的n的因子的连续区间的长度为多少
思路:结论表明最长的区间必然是从1开始的区间,假设我们找到的1到5这个区间都是因子,如果存在一个区间的长度是大于这个区间的话,比如9-14,那么我们可以发现其中的长度是等于6的,那么证明其中一定存在6的因子,那么其实就可以发现我们前面那个区间的长度又可以扩大了,1-6,依次类推,那么我们就可以从1枚举,找到第一个不是因子的数i,i-1为答案
diamond:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
const int mod=1e9 +7 ;
int fa[100005 ];
int n,m;
void solve () {
unordered_map<ll, ll> has;
int x;
cin >> x;
int ans=0 ;
int p=0 ;
for (int i = 1 ; i <=500 ; ++i) {
if (x%i==0 ){
p++;
}
else {
ans=max (ans,p);
p=0 ;
}
}
ans=max (p,ans);
cout<<ans<<'\n' ;
}
signed main () {
ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 );
int t;
cin>>t;
while (t--){
solve ();
}
}
题意:给一个数组,每次操作我们可以把一个数加到另一个数上,可以加本身,问我们怎么操作才能使数组是递增的
思路:直接按照Hard版本的讲,我们可以看到题目给的次数是次,如果我们数组全部为正或为负,那么我们最多19次求一遍前缀和或者后缀和即可,那么如果存在不同的,我们其他的12次就可以用来变负为正或者变正为负的操作,假设我们得到,正的绝对值>=负的绝对值,我们首先考虑变负为正,我们最多变12次,那么当负的个数<=12,我们就可以直接操作,假设>12,那么考虑把正的变为负,因为正的只有<=7个,我们先把变为大于等于,最差情况,min=-1,我们对他进行加自己的操作,那么-1 -2 -4 -8 -16 -32,最差进行5次操作即可>=正的最大值,最后把正的变为负,再进行后缀和操作,刚好是5+7+19=31次操作,如果,反过来操作即可
diamond:
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9 +7 ;
int fa[100005 ];
int n,m;
#define endl '\n'
void solve () {
cin>>n;
vector<int >g (n+1 );
vector<pair<int ,int >>ans;
int ma=-99 ,mi=99 ;
int idxma=0 ,idxmi;
int zheng=0 ,fu=0 ;
for (int i = 1 ; i <=n ; ++i) {
cin>>g[i];
if (g[i]>=0 )zheng++;
else
fu++;
if (ma<g[i]) {
ma = max (ma, g[i]);
idxma=i;
}
if (mi>g[i]) {
mi = min (mi, g[i]);
idxmi=i;
}
}
if (mi>=0 ){
cout<<n-1 <<endl;
for (int i = 1 ; i <=n-1 ; ++i) {
cout<<i+1 <<' ' <<i<<endl;
}
return ;
}
if (ma<=0 ){
cout<<n-1 <<endl;
for (int i = n; i >1 ; --i) {
cout<<i-1 <<' ' <<i<<endl;
}
cout<<endl;
return ;
}
if (abs (ma)>=abs (mi)){
if (fu<=12 ){
for (int i = 1 ; i <=n ; ++i) {
if (g[i]<0 ){
ans.push_back ({i,idxma});
}
}
for (int i = 1 ; i <=n-1 ; ++i) {
ans.push_back ({i+1 ,i});
}
}
else {
for (int i = 0 ; i <5 ; ++i) {
ans.push_back ({idxmi,idxmi});
}
for (int i = 1 ; i <=n ; ++i) {
if (g[i]>=0 ){
ans.push_back ({i,idxmi});
}
}
for (int i = n; i >1 ; --i) {
ans.push_back ({i-1 ,i});
}
}
}
else {
if (zheng<=12 ){
for (int i = 1 ; i <=n ; ++i) {
if (g[i]>=0 ){
ans.push_back ({i,idxmi});
}
}
for (int i = n; i >1 ; --i) {
ans.push_back ({i-1 ,i});
}
}
else {
for (int i = 0 ; i <5 ; ++i) {
ans.push_back ({idxma,idxma});
}
for (int i = 1 ; i <=n ; ++i) {
if (g[i]<0 ){
ans.push_back ({i,idxma});
}
}
for (int i = 1 ; i <=n-1 ; ++i) {
ans.push_back ({i+1 ,i});
}
}
}
cout<<ans.size ()<<endl;
for (auto i:ans) {
cout<<i.first<<' ' <<i.second<<endl;
}
}
signed main () {
ios::sync_with_stdio (false ),cin.tie (0 ),cout.tie (0 );
int t;
cin>>t;
while (t--){
solve ();
}
}
题意:给n张牌,每张牌的价值是,刚开始除了第一张,每一张牌都上锁了,在开锁的牌里选一张,进行操作,操作有两种,第一种是解锁V个没有解锁的牌,从上往下依次,第二种操作是ans+=V;问答案的最大值是多少
思路:我们可以发现,解锁的牌数和价值是等价的,比如 ,当你解锁3张牌时,你的答案就是,这就是最大,假设用掉了x张牌,就说明x张牌都是解锁的花了(x-1)的点数去解锁,剩下的就是贡献,即是(第一张牌不用解锁),sum为前缀和,我们的做法是去枚举ans取最大即可,即是枚举x
:即是用DP求每一张牌的状态x,由于DP是n^2,所有我们用bitset表示状态,例如2 4 5 0 1,bt状态为1 0 0 0 0,代表刚开始只有第一张牌是解锁的,那么我们就可以操作2求一遍ans,然后我们进行操作1,那么我们的bt状态就变成了0 0 1 0 0 ,1前面的都是解锁了的,当我们遍历到idx=1时,我们发现,这时不用更新ans,因为你如果对idx=1的位置进行操作2,其实在idx=2的位置进行操作2时就已经包括了,在3时更新明显更优,那么在idx=1时由于bt[1]=0我们只有一种操作,就是对他进行操作1,那么我们的bt就变成了0 0 1 0 0 0 1,然后遍历到2时发现,idx=1,那么我们对他进行操作2,更新ans,然后进行操作1,因为对idx=1时,他可以不进行操作1,也可以进行操作1,那么idx=2进行操作1时,就会产生两种情况,bt就变成了0 0 0 0 0 0 1 1 0 0 1,变成了这种情况,最后两个1即是新产生的两种情况,依次类推,每一个1都代表了一种独立的情况,这些1的位置最多是在2 * n-1的位置,在大于n时,其实就代表了最后解锁时你剩余的牌数小于这个值V,这样也符合题意,我们得到的新的1会溢出,遍历到1时,我们更新,是正确的。
diamond:
#include <iostream>
#include <string>
#include <cstdio>
#include <bitset>
using namespace std;
#define debug 0
const int maxn = 200010 ;
#define ll long long
int n;
int a[maxn];
bitset<maxn> dp;
void solve () {
scanf ("%d" , &n);
for (int i = 0 ; i < n; ++i) {
scanf ("%d" , &a[i]);
}
n <<= 1 ;
ll ans = 0 , sum = 0 ;
dp[0 ] = 1 ;
for (int i = 0 ; i < n; ++i) {
dp |= (dp << a[i]);
sum += a[i];
if (dp[i] == 1 ) {
ans = max (ans, sum - i);
dp[i] = 0 ;
}
}
printf ("%lld\n" , ans);
}
int main () {
int t = 1 ;
while (t--) {
solve ();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】