A
小學數學題
#include<bits/stdc++.h>
using namespace std;
long long f[102];
void init(){
f[1]=1;
for(int i=2;i<=101;i++){
f[i]=f[i-1]+(i-1)*4;
}
}
int main(){
init();
int n;
cin>>n;cout<<f[n]<<endl;
return 0;
}
B
題意:
現在有一個數組,你可以選擇若干個將它們變成,使得他們的乘積最大。輸出一種可行方案
思路:
先把所有的非負數變爲,然後統計現在負數的個數,若爲偶數,則不操作,否則選擇最小的那個負數變爲。
代碼:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+100;
int a[N];
int main(){
int n;
int neg=0;
cin>>n;for(int i=1;i<=n;i++){
cin>>a[i];if(a[i]>=0) a[i]=-a[i]-1;
}
for(int i=1;i<=n;i++){
if(a[i]<0) neg++;
}
if(neg&1){
int minn=0;
for(int i=1;i<=n;i++) minn=min(minn,a[i]);
for(int i=1;i<=n;i++){
if(a[i]==minn){
a[i]=-a[i]-1;break;
}
}
}
for(int i=1;i<=n;i++) cout<<a[i]<<' ';
cout<<endl;
return 0;
}
C
題意:
一個長度爲的雙端隊列,你執行無數次下列操作:取出隊列頂端的前兩個數,大的放在隊列頂端,小的放到隊列尾部,現在給你次查詢,查詢每次操作的。
思路:
手動模擬一遍一會發現,前次是不確定的,經過次之後變成了每次一個循環,因此只需先記錄次,然後對於查詢直接查詢即可,複雜度
代碼:
#include<bits/stdc++.h>
using namespace std;
int main(){
long long n,m,x;
scanf("%I64d%I64d",&n,&m);
map<long long ,pair<long long,long long> > mmp1,mmp2;
deque<long long> q;
for(int i=1;i<=n;i++){
scanf("%I64d",&x);q.push_back(x);
}
for(int j=1;j<=n;j++){
int A=q.front();q.pop_front();
int B=q.front();q.pop_front();
//cout<<j<<' '<<A<<' '<<B<<endl;
mmp1[j]={A,B};
if(A>B){
q.push_front(A);
q.push_back(B);
}
else{
q.push_front(B);
q.push_back(A);
}
}
for(int j=1;j<=n-1;j++){
int A=q.front();q.pop_front();
int B=q.front();q.pop_front();
//cout<<j<<' '<<A<<' '<<B<<endl;
mmp2[j]={A,B};
if(A>B){
q.push_front(A);
q.push_back(B);
}
else{
q.push_front(B);
q.push_back(A);
}
}
long long Q;
while(m--){
scanf("%I64d",&Q);
if(Q<=n){
printf("%I64d %I64d\n",mmp1[Q].first,mmp1[Q].second);
}
else{
Q-=n;
if(Q%(n-1)==0) printf("%I64d %I64d\n",mmp2[n-1].first,mmp2[n-1].second);
else printf("%I64d %I64d\n",mmp2[Q%(n-1)].first,mmp2[Q%(n-1)].second);
}
}
return 0;
}
D
題意:
一個的網狀圖,你要訪問每個格點,你的初始格點在,現在你可以從到達,你要構造一個遍歷順序使得每次的都不相同並且能遍歷完所有的點。
思路
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;cin>>n>>m;
for(int i=1;i<=n/2;i++){
for(int j=1;j<=m;j++){
printf("%d %d\n",i,j);
printf("%d %d\n",n+1-i,m+1-j);
//<<n+1-i<<' '<<m+1-j<<endl;
}
}
if(n&1){
if(m&1){
for(int i=1;i<=m/2;i++){
printf("%d %d\n",n/2+1,i);
printf("%d %d\n",n/2+1,m+1-i);
}
printf("%d %d\n",n/2+1,m/2+1);
//cout<<n/2+1<<' '<<m/2+1<<endl;
}
else{
for(int i=1;i<=m/2;i++){
printf("%d %d\n",n/2+1,i);
printf("%d %d\n",n/2+1,m+1-i);
//cout<<n/2+1<<' '<<m+1-i<<endl;
}
}
}
return 0;
}
E
題意:
有盤菜,個學生,每盤菜的價格爲,每個學生帶的錢爲,每個學生會買他所能買的最貴的菜,現在有次修改,每次你可以把變爲,或者把變爲,對於每次修改,計算剩下的最貴的菜的價格,如果沒有,則輸出。
思路:
對於每個,我們將區間加,對於每個,我們將區間減,每次查詢統計最大的不爲的數,如果沒有輸出,線段樹即可完成操作,複雜度
代碼:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6+100;
int tag[N<<1],maxx[N<<1];
int a[N],b[N];
void pushdown(int rt,int l,int r){
if(tag[rt]){
tag[rt<<1]+=tag[rt];
tag[rt<<1|1]+=tag[rt];
maxx[rt<<1]+=tag[rt];
maxx[rt<<1|1]+=tag[rt];
tag[rt]=0;
}
}
void update(int rt,int nl,int nr,int l,int r,int x){
if(nl<=l&&r<=nr){
maxx[rt]+=x;
tag[rt]+=x;
return ;
}
int mid=(l+r)>>1;
pushdown(rt,l,r);
if(nl<=mid) update(rt<<1,nl,nr,l,mid,x);
if(nr>mid) update(rt<<1|1,nl,nr,mid+1,r,x);
maxx[rt]=max(maxx[rt<<1|1],maxx[rt<<1]);
}
int query(int rt,int l,int r){
if(l==r){
return l;
}
int mid=(l+r)>>1;
pushdown(rt,l,r);
if(maxx[rt<<1|1]>0){
return query(rt<<1|1,mid+1,r);
}
return query(rt<<1,l,mid);
}
int main(){
int n,m,q;
scanf("%d %d",&n,&m);
memset(maxx,0,sizeof(maxx));
memset(tag,0,sizeof(tag));
for(int i=1;i<=n;i++) scanf("%d",&a[i]),update(1,1,a[i],1,2000002,1);
for(int i=1;i<=m;i++) scanf("%d",&b[i]),update(1,1,b[i],1,2000002,-1);
//cout<<query(1,1,2000002)<<endl;
scanf("%d",&q);
while(q--){
int op,id,num;
scanf("%d %d %d",&op,&id,&num);
if(op==1){
update(1,1,a[id],1,2000002,-1);
a[id]=num;
update(1,1,a[id],1,2000002,1);
}
else{
update(1,1,b[id],1,2000002,1);
b[id]=num;
update(1,1,b[id],1,2000002,-1);
}
int ok=query(1,1,2000002);
if(maxx[1]<=0) puts("-1");
else printf("%d\n",ok);
}
return 0;
}