//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A 358A Dima and Continuous Line
题意:
题解:mdzz 想复杂了,wa了一万年。我可能是个傻逼。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define de(x) cout << #x << "=" << x << endl
const int N=1005;
int a[N];
struct Node {
int x,y;
}b[N];
int main() {
int n;
while(~scanf("%d",&n)) {
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<n;++i) {
int x=a[i],y=a[i+1];
if(x>y) swap(x,y);
b[i].x=x;
b[i].y=y;
}
--n;
int ans=0;
for(int i=1;i<=n;++i) {
for(int j=1;j<=n;++j) {
if(i==j) continue;
int x1=b[i].x,y1=b[i].y;
int x2=b[j].x,y2=b[j].y;
if((x1<x2&&x2<y1&&y1<y2)||(x2<x1&&x1<y2&&y2<y1)) {
ans=1;
break;
}
}
}
if(ans) {
puts("yes");
} else {
puts("no");
}
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
题意:三个容器。栈,队列,双端队列。
两种操作:
1、压入一个数在任意一个容器。
2、从三个容器中弹出一个数。(如果容器为空,不用弹出)。弹出后清空。
n次操作之后要让弹出的数总和最大。输出所有操作。
题解:模拟。最大的放在三个容器。其他的都放在双端队列的另一端。
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
struct Node {
int val,i,tag;
}a[N],b[N];
bool cmp1(Node a,Node b) {
if(a.val==b.val) return a.i<b.i;
return a.val>b.val;
}
bool cmp2(Node a,Node b) {
return a.i<b.i;
}
int main() {
int n;
while(~scanf("%d",&n)) {
int m=0;
for(int i=1;i<=n;++i) {
scanf("%d",&a[i].val);
a[i].i=i;
a[i].tag=0;
b[++m]=a[i];
if(a[i].val==0) {
sort(b+1,b+m,cmp1);
int cnt=0;
for(int j=1;j<m&&j<=3;++j) {
b[j].tag=1;
++cnt;
}
sort(b+1,b+m,cmp2);
int p=0;
for(int j=1;j<m;++j) {
if(b[j].tag) {
if(p==0) puts("pushStack");
else if(p==1) puts("pushQueue");
else if(p==2) puts("pushFront");
++p;
} else {
puts("pushBack");
}
}
printf("%d",cnt);
if(cnt>=1) printf(" popStack");
if(cnt>=2) printf(" popQueue");
if(cnt>=3) printf(" popFront");
puts("");
m=0;
}
}
for(int i=1;i<=m;++i) puts("pushBack");
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
题意:喂n只兔子。给出三个数组。
a[i]表示喂第i只兔子时,它的左右都还没被喂的收益。
b[i]表示喂第i只兔子时,它的左右只被喂了一只的收益。
c[i]表示喂第i只兔子时,它的左右都被喂了的收益。
d[i][0][1]表示喂第i只兔子时,它的右边被喂了。
d[i][1][0]表示喂第i只兔子时,它的左边被喂了。
d[i][1][1]表示喂第i只兔子时,它的左右都被喂了。
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=3005;
int a[N][3],d[N][2][2];
int main() {
int n;
while(~scanf("%d",&n)) {
for(int i=0;i<3;++i)
for(int j=1;j<=n;++j)
scanf("%d",&a[j][i]);
d[1][1][0]=d[1][1][1]=-99999999;
d[1][0][0]=a[1][0];
d[1][0][1]=a[1][1];
for(int i=2;i<=n;++i) {
d[i][0][0]=max(d[i-1][0][1],d[i-1][1][1])+a[i][0];
d[i][0][1]=max(d[i-1][0][1],d[i-1][1][1])+a[i][1];
d[i][1][0]=max(d[i-1][0][0],d[i-1][1][0])+a[i][1];
d[i][1][1]=max(d[i-1][0][0],d[i-1][1][0])+a[i][2];
}
printf("%d\n",max(d[n][0][0],d[n][1][0]));
}
return 0;
}
#include<cstdio>
#include<cstring>
const int N=1005;
int a[N][N],duandian[N][N],vis[N][N];
int n,m;
int check(int x,int y) {
int shang=a[x-1][y];
int you=a[x][y+1];
int xia=a[x+1][y];
int zuo=a[x][y-1];
int t=shang+you+xia+zuo;
if(t==2) {
if(shang&&xia) t=0;
if(zuo&&you) t=0;
}
return t;
}
int gcd(int a,int b) {
if(b==0) return a;
return gcd(b,a%b);
}
void dfs(int x,int y) {
vis[x][y]=1;
int shang=a[x-1][y]&&!vis[x-1][y];
int you=a[x][y+1]&&!vis[x][y+1];
int xia=a[x+1][y]&&!vis[x+1][y];
int zuo=a[x][y-1]&&!vis[x][y-1];
if(shang) dfs(x-1,y);
if(you) dfs(x,y+1);
if(xia) dfs(x+1,y);
if(zuo) dfs(x,y-1);
}
int main() {
while(~scanf("%d%d",&n,&m)) {
memset(a,0,sizeof(a));
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%d",&a[i][j]);
//欧拉图
//1、判断联通
memset(vis,0,sizeof(vis));
int flag=1;
for(int i=1;i<=n&&flag;++i)
for(int j=1;j<=m&&flag;++j)
if(a[i][j]) {
dfs(i,j);
flag=0;
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(a[i][j]&&!vis[i][j]) {
puts("-1");
return 0;
}
//2、奇度点的个数
memset(duandian,0,sizeof(duandian));
int cnt=0;
for(int i=1;i<=n&&cnt<=2;++i) {
for(int j=1;j<=m&&cnt<=2;++j) {
if(!a[i][j]) continue;
int t=check(i,j);
if(t) duandian[i][j]=1;
if(t&1) ++cnt;
}
}
if(cnt==1||cnt>2) {
puts("-1");
continue;
}
//所有边的长度
memset(vis,0,sizeof(vis));
int ans=0;
for(int i=1;i<=n;++i) {
for(int j=1;j<=m;++j) {
if(!duandian[i][j]) continue;
int x=i,y=j;
int shang=a[x-1][y]&&!vis[x-1][y];
int you=a[x][y+1]&&!vis[x][y+1];
int xia=a[x+1][y]&&!vis[x+1][y];
int zuo=a[x][y-1]&&!vis[x][y-1];
if(shang) {
int t=x-1;
while(a[t][y]&&!vis[t][y]&&!duandian[t][y]) --t;
ans=gcd(ans,x-t);
}
if(you) {
int t=y+1;
while(a[x][t]&&!vis[x][t]&&!duandian[x][t]) ++t;
ans=gcd(ans,t-y);
}
if(xia) {
int t=x+1;
while(a[t][y]&&!vis[t][y]&&!duandian[t][y]) ++t;
ans=gcd(ans,t-x);
}
if(zuo) {
int t=y-1;
while(a[x][t]&&!vis[x][t]&&!duandian[x][t]) --t;
ans=gcd(ans,y-t);
}
}
}
if(ans<=1) {
puts("-1");
} else {
for(int i=2;i<=ans;++i) {
if(ans%i==0) printf("%d ",i);
}
puts("");
}
}
return 0;
}