Minimize Abs 1
一定不能使用o(n^2)的算法,会超时
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f
#define N 200005
//int ans=0,sum=0;
int n,m;
vector<int> qz(N),qj(N),dp(N);
//vector<int> nums(N);
//int s[N][N];
//bool vis[N][N] = {false};
//vector<int> a(N),b(N);
//pair<int,int> pa(1,10);
//vector<int> a(N);
int ans=0;
bool vis[N]={false};
vector<int> jue(N);
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,l,r;
cin>>n>>l>>r;
for(int i=1;i<=n;i++) //相当于距离最小问题,就是一个数距离一个区间所有数的最短距离
{
int x;
cin>>x;
if(x<=l) cout<<l<<" ";//在区间外的左边,则距离左端点最近
else if(x>=r) cout<<r<<" ";//在区间外的右边,则距离右端点最近
else cout<<x<<" ";//在区间里面则距离最短为0
}
return 0;
}
Atcoder ARC174 A -A Multiply
动态规划关于最大、最小子序列和
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f
#define N 300005
//int ans=0,sum=0;
int n,m;
//vector<int> qz(N),qj(N),dp(N);
//vector<int> nums(N);
//int s[N][N];
//bool vis[N][N] = {false};
vector<int> a(N),b(N);
//pair<int,int> pa(1,10);
vector<int> dp(N);
//int ans=0;
//bool vis[N]={false};
//vector<int> jue(N);
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,c,sum=0;
cin>>n>>c;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
//子序列和最大的问题,主要是考虑c》0时候,和c《=0时候,注意c==0不是一种单独的情况,它要把最小的子序列和给去掉。
if(c>0)
{
int maxvalue=a[1];
dp[1] = a[1];
for(int i=2;i<=n;i++)
{
dp[i] = max(dp[i-1]+a[i],a[i]);
maxvalue = max(dp[i],maxvalue);
}
cout<<max((c-1)*maxvalue+sum,sum);
}
if(c<=0)//c==0放在这儿可以消掉为负数的最小子序列和,最大化数组和
{
int minvalue=a[1];
dp[1] = a[1];
for(int i=2;i<=n;i++)
{
dp[i] = min(dp[i-1]+a[i],a[i]);
minvalue=min(minvalue,dp[i]);
}
cout<<max((c-1)*minvalue+sum,sum);
}
return 0;
}
Minimize Abs 2
二分法的使用
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f
#define N 300005
//int ans=0,sum=0;
int n,m;
//vector<int> qz(N),qj(N),dp(N);
//vector<int> nums(N);
//int s[N][N];
//bool vis[N][N] = {false};
vector<int> a(N),b(N);
//pair<int,int> pa(1,10);
vector<int> dp(N);
//int ans=0;
//bool vis[N]={false};
//vector<int> jue(N);
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int d;
cin>>d;
int ans=INF;
for(int x=0;x<=2e6;x++)//根据d的范围确定x的上限
{
int l=0,r=2e6;//然后在这个范围用二分查找y
while(l<=r)//找出最小的距离
{
int y=(l+r)/2;
ans=min(ans,abs(x*x+y*y-d));
if(x*x+y*y<d) l=y+1;
else r=y-1;
}
}
cout<<ans<<endl;
return 0;
}
Counting Ls
用到乘法定理,注意开头的输入
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f
//这个题要求如下:
//三个格子内都是 o
//三个方格互不相同
//恰好有两个方格在同一行
//恰好有两个方格在同一列
/*题解:
根据要求:我们可以知道满足要求的三方格组,一定是L型的,要统计三方格组的数目,首先我们可以统计每一行的O和每一列o的数目,分别顶替为
row[2005],col[2005],然后想想如果一个点是o,从纵向和横向出发,除去本身的这个o,那么两个方向上任意的两个点,就可以组成一个三元组
,那么要知道它的种数,则利用乘法原理(row[i]-1)*(col[j]-1)就是该点为o的三方格数目,如此遍历矩阵中每一个o,将所有的(row[i]-1)*(col[j]-1)相加。
*/
char s[2005][2005];
int row[2005],col[2005];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;string si;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>si;
for(int j=0;j<n;j++)
{
s[i][j+1]=si[j];
if(si[j]=='o') row[i]++;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(s[j][i]=='o')
{
col[i]++;
}
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(s[i][j]=='o')
{
ans+=((row[i]-1)*(col[j]-1));
}
}
}
cout<<ans<<endl;
return 0;
}