目录
B 、Crazy Binary String (思维)
题意:
计算最长的01子串和子序列,其中01数量相同。
分析:
对于子串那么直接将0制成-1,1还是1计算前缀和,然后相减为零的最大长度即为答案
对于子序列也就是计算最小的0 或 1 的数量。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
char s[maxn];
int pre[maxn];
map<int,int> mp;
int main(){
int n;
scanf("%d%s",&n,s+1);
int ans1=0,ans2=0;
for(int i=1;i<=n;i++){
pre[i]=pre[i-1]+(s[i]=='0'?-1:1);
ans2+=s[i]-'0';
if(mp[pre[i]]==0&&pre[i]!=0){
mp[pre[i]]=i;
}else{
ans1=max(ans1,i-mp[pre[i]]);
}
}
printf("%d %d\n",ans1,min(ans2<<1,(n-ans2)<<1));
return 0;
}
D 、Big Integer ( 数论 )
题意:
定义 表示有n个1,计算 ,i,j 范围均为1e9
分析:
#include<bits/stdc++.h>
#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define PI acos(-1.0)
#define E exp(1.0)
//#define io
using namespace std;
const int inf=0x3f3f3f3f;
ll quick_mul(ll a,ll b,ll mod){
ll res=0;
while(b){
if(b&1) res=(res+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return res;
}
ll quick_pow(ll a,ll b,ll mod){
ll ans=1;
while(b){
if(b&1) ans=quick_mul(ans,a,mod)%mod;
a=quick_mul(a,a,mod)%mod;
b>>=1;
}
return ans;
}
ll quick_pow(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans=ans*a;
a=a*a;
b>>=1;
}
return ans;
}
ll yin[1000000][2];
int main(){
#ifdef io
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T;
scanf("%d",&T);
while(T--){
ll p,n,m;
scanf("%lld%lld%lld",&p,&n,&m);
if(p==2||p==5){
printf("0\n");
continue;
}
ll xun=6ll*(p-1);
ll temp=xun;
for(ll i=1;i*i<=temp;i++){
if(temp%i==0) {
if(quick_pow(10,i,9ll*p)==1){
xun=min(xun,i); break;
}else if(quick_pow(10,temp/i,9ll*p)==1){
xun=min(xun,temp/i);
}
}
}
int tot=0;
for(ll i=2;i*i<=xun;i++){
if(xun%i==0){
tot++;
int cnt=0;
yin[tot][0]=i;
yin[tot][1]=0;
while(xun%i==0){
xun/=i;
yin[tot][1]++;
}
}
}
if(xun>1){
yin[++tot][0]=xun;
yin[tot][1]=1;
}
ll ans=0;
for(int j=1;j<=32&&j<=m;j++){
ll tmp=1;
for(int k=1;k<=tot;k++){
tmp=tmp*quick_pow(yin[k][0],(yin[k][1]+j-1)/j);
}
ans+=n/tmp;
}
ll tmp=1;
for(int k=1;k<=tot;k++){
tmp=tmp*yin[k][0];
}
ans+=n/tmp*max(0ll,m-33+1);
printf("%lld\n",ans);
}
return 0;
}
F 、Planting Trees(思维+单调队列)
题意:
给出一个矩阵,计算最大的矩形使得所有元素的差值在m之内。
分析:
的做法,首先固定上下行进行枚举,计算出每列的最大最小值,用单调队列进行维护,
同时注意每次不满足条件的时候进行更新。还有注意细节
#include<bits/stdc++.h>
#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define PI acos(-1.0)
#define E exp(1.0)
//#define io
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=505;
int a[maxn][maxn];
int mn[maxn],mx[maxn];
int q1[maxn],q2[maxn];
int main(){
#ifdef io
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
}
}
int ans=0;
for(int u=1;u<=n;u++){
for(int i=1;i<=n;i++) mx[i]=0,mn[i]=inf;
for(int d=u;d<=n;d++){
int l1,l2,r1,r2;
l1=l2=r1=r2=0;
int tmp=0;
for(int i=1;i<=n;i++){
mn[i]=min(mn[i],a[d][i]);
mx[i]=max(mx[i],a[d][i]);
while(l1<r1&&mn[q1[r1-1]]>mn[i]) r1--;
while(l2<r2&&mx[q2[r2-1]]<mx[i]) r2--;
q1[r1++]=i;q2[r2++]=i;
while(l1<r1&&l2<r2&&mx[q2[l2]]-mn[q1[l1]]>m) {
if(q1[l1]<q2[l2]){
tmp=q1[l1]; //注意这块的顺序。
l1++;
}else{
tmp=q2[l2];
l2++;
}
}
ans=max(ans,(d-u+1)*(i-tmp));
}
}
}
printf("%d\n",ans);
}
return 0;
}
H、 Magic Line (计算几何)
题意:
将给出的点用一条直线分为两堆,计算正好平分所有点的一条直线,输出坐标,其中坐标均为整数
分析:
将所有点排个序取中间点即可。然后选取个很大的点,狗成一条直线,就能正好评分。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
struct node{
int x,y;
bool operator < (const node p){
if(x==p.x) return y>p.y;
return x<p.x;
}
}a[maxn];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
// printf("%d %d\n",a[i].x,a[i].y);
}
sort(a+1,a+n+1);
// cout<<endl;
// for(int i=1;i<=n;i++){
// cout<<a[i].x<<" "<<a[i].y<<endl;
// }
int cnt=n/2;
int x1,x2,y1,y2;
if(a[cnt].x==a[cnt+1].x){
x1=a[cnt].x-1;
x2=x1+2;
y1=-1e8;
y2=a[cnt+1].y-y1+a[cnt+1].y+1;
}else{
x1=a[cnt].x;
y1=-1e8;
x2=x1+1;
y2=a[cnt].y-y1+a[cnt].y;
}
printf("%d %d %d %d\n",x1,y1,x2,y2);
}
}
J、 LRU management (模拟)
题意:
给出一系列操作进行模拟;
分析:
注意的就是用STL的时候要用unordered_map,因为map是基于红黑树实现的,underorder_map是基于哈希表实现的,所以一个复杂度是logn,一个是1.
还要注意如果用c++加速读入的话不能和scanf一起读。
#include<bits/stdc++.h>
#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define PI acos(-1.0)
#define E exp(1.0)
//#define io
using namespace std;
const int inf=0x3f3f3f3f;
struct node{
string s;
int v;
};
typedef list<node>::iterator iter;
int main(){
#ifdef io
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
int n,m;
cin>>n>>m;
list<node> lis;
unordered_map<string,iter> mp;
int cnt=0;
while(n--){
int op,v;
string s;
cin>>op>>s>>v;
if(op==0){
int ans;
if(mp.find(s)!=mp.end()){
auto it=mp[s];
lis.erase(it);
lis.push_back(node{s,it->v});
it=lis.end();it--;
mp[s]=it;
ans=it->v;
}else{
lis.push_back(node{s,v});
cnt++;
auto it=lis.end();
it--;
mp[s]=it;
ans=v;
if(cnt>m){
auto it=lis.begin();
mp.erase(it->s);
lis.pop_front();
cnt--;
}
}
printf("%d\n",ans);
}else{
if(mp.find(s)==mp.end()){
printf("Invalid\n");
}else{
auto it=mp[s];
if(v==0){
printf("%d\n",it->v);
}else if(v==1){
it++;
if(it==lis.end()) printf("Invalid\n");
else printf("%d\n",it->v);
}else{
if(it==lis.begin()){
printf("Invalid\n");
}else{
it--;
printf("%d\n",it->v);
}
}
}
}
}
}
return 0;
}