A
分析:bfs过程中记录前驱就行了。
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 1000+11;
int to[4][2]={1,0,-1,0,0,1,0,-1};
int n=5;
int mp[N][N];
bool vis[N][N];
struct Node{
int x,y,step;
};
int pre[N*N];
int getid(int x,int y){
return (x-1)*n+y;
}
stack<Node>S;
void bfs(){
queue<Node>que;
Node st={1,1,0}; pre[getid(1,1)]=-1;
que.push(st); vis[st.x][st.y]=1;
while(!que.empty()){
Node now=que.front(); que.pop();
if(now.x==n && now.y==n){
break;
}
for(int i=0;i<4;i++){
int nx=now.x+to[i][1]; int ny=now.y+to[i][0];
if(nx<1||nx>n ||ny<1||ny>n) continue;
if(vis[nx][ny]) continue;
if(mp[nx][ny]==1) continue;
pre[getid(nx,ny)]=getid(now.x,now.y);
Node ne={nx,ny,now.step+1};
vis[nx][ny]=1;
que.push(ne);
}
}
// cout<<pre[getid(n,n)]<<endl;;
//cout<<pre[getid(4,5)]<<endl;
//puts("====");
int x,y;
x=y=n;
Node next={n,n,0};
S.push(next);
int id=getid(n,n);
while(1){
if(id==1) break;
int xu = pre[id];
int nx=(xu-1)/n+1 ; int ny=xu-(nx-1)*n;
Node ne={nx,ny,0};
S.push(ne);
id=pre[id];
}
while(!S.empty()){
Node now=S.top();S.pop();
printf("(%d, %d)\n",now.x-1,now.y-1);
}
}
int main(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&mp[i][j]);
}
}
bfs();
return 0;
}
B
分析:java水过
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
import java.util.Scanner;
/* Name of the class has to be "Main" only if the class is public. */
class Main
{
public static BigInteger[] A = new BigInteger[1000];
public static void main (String[] args) throws java.lang.Exception
{
Scanner cin = new Scanner (System.in);
while(cin.hasNext()){
A[0]=cin.nextBigInteger();
A[1]=cin.nextBigInteger();
A[2]=cin.nextBigInteger();
for(int i=3;i<105;i++){
A[i]=A[i-1].add(A[i-2].add(A[i-3]));
}
BigInteger t=A[99];
System.out.println(t);
}
// your code goes here
}
}
C
分析:最小费用最大流的经典题目 。
DP也可以解,但是不会哎 ,ε=(´ο`*)))唉
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 1e5+11;
const int M = 2e5+11;
const int inf = 0x3f3f3f3f;
struct Edge {
int from,to,cap,flow,cost,next;
} edge[M];
int head[N],top;
void init() {
memset(head,-1,sizeof(head));
top=0;
}
void addedge(int a,int b,int w,int c) {
edge[top].from=a;
edge[top].to=b;
edge[top].cap=w;
edge[top].flow=0;
edge[top].cost=c;
edge[top].next=head[a];
head[a]=top++;
edge[top].from=b;
edge[top].to=a;
edge[top].cap=0;
edge[top].flow=0;
edge[top].cost=-c;
edge[top].next=head[b];
head[b]=top++;
}
int dis[N];
bool vis[N];
int pre[N];
bool spfa(int s,int t) {
queue<int>q;
for(int i=0; i<N; i++) {
dis[i]=inf;
vis[i]=false;
pre[i]=-1;
}
dis[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty()) {
int now=q.front();
q.pop();
vis[now]=false;
for(int i=head[now]; i!=-1; i=edge[i].next) {
int v=edge[i].to;
if(edge[i].cap >edge[i].flow && dis[v] > dis[now]+edge[i].cost) {
dis[v] =dis[now]+edge[i].cost;
pre[v]=i;
if(!vis[v]) {
vis[v]=true;
q.push(v);
}
}
}
}
if(pre[t]==-1) return false;
else return true;
}
int mcmf(int s,int t,int &cost) {
int flow=0;
cost=0;
while(spfa(s,t)) {
int Min=inf;
for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to]) {
Min=min(Min,edge[i].cap-edge[i].flow);
}
for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to]) {
edge[i].flow+=Min;
edge[i^1].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
int n,m;
int getid(int x,int y) { return (x-1)*m+y;
}
int mp[110][110];
int main() {
int T ;
scanf("%d",&T); int cas=1;
while(T--) {
init();
scanf("%d%d",&n,&m);
int S=0,T=n*m+n*m+10;
addedge(S,1,2,0);
addedge(getid(n,m)+n*m,T,2,0);
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
scanf("%d",&mp[i][j]);
if(i==n && j==m) addedge(getid(i,j),getid(i,j)+n*m,2,0);
else if(i==1 && j==1 ) addedge(getid(i,j),getid(i,j)+n*m,2,0);
else addedge(getid(i,j),getid(i,j)+n*m,1,-mp[i][j]);
}
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
int nx=i+1; int ny=j;
if(nx<1|| nx>n ||ny<1||ny>m) ;
else {
addedge(getid(i,j)+n*m,getid(nx,ny),1,0) ;
}
nx=i; ny=j+1;
if(nx<1|| nx>n ||ny<1||ny>m) ;
else {
addedge(getid(i,j)+n*m,getid(nx,ny) ,1,0) ;
}
}
}
int cost;
mcmf(S,T,cost);
printf("Case %d: %d\n",cas++,-cost+mp[1][1]+mp[n][m]);
}
return 0;
}
D
分析: 模拟 ,注意题目格式
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 1e5+11;
char s[N];
int main(){
int T;cin>>T;
int have=0;
while(T--){
if(have++) puts("");
int n;scanf("%d",&n);
getchar();
while(n--){
gets(s);
string ss="";
for(int i=0;s[i];i++){
if(s[i]==' '){
reverse(ss.begin(),ss.end());
cout<<ss;
putchar(' ');
ss="";
}else ss+=s[i];
}
if(ss!="") {
reverse(ss.begin(),ss.end());
cout<<ss;
}
puts("");
}
}
return 0;
}
E
分析:模拟
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 1e5+11;
int main(){
LL n;
while(cin>>n){
LL m=n;
LL ans=0;
while(n){
LL t=n%10;
ans+=t*t*t;
n/=10;
}
if(ans==m) puts("Yes");
else puts("No");
}
return 0;
}
F
分析:模拟 暴力
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 200+11;
int mp[N][N];
int to[4][2]={1,0,-1,0,0,1,0,-1};
int main(){
int n,m;
while(cin>>n>>m){
if(n==0 && m==0) break;
int ff=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&mp[i][j]);
if(mp[i][j]==0) ff=1;
}
}
int flag=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mp[i][j]==1) continue;
for(int k=0;k<4;k++){
int nx=i+to[k][0] ;int ny=j+to[k][1];
if(nx<1||nx>n || ny<1|| ny>m) continue;
if(mp[nx][ny]==0) flag=0;
}
}
}
if(flag && ff) puts("Yes");
else puts("No");
}
return 0;
}
G
分析:模拟暴力
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 1e6+11;
bool su[N]={1,1,0};
void init(){
for(LL i=2;i<N;i++){
if(!su[i]) {
for(LL j=i*i;j<N;j+=i){
su[j]=1;
}
}
}
}
int main(){
init();
LL n;
while(cin>>n){
int flag=0;
for(int i=2;i*i<=n;i++){
if(!su[i]){
if(n%i==0){
if(!su[n/i]){
flag=1;break;
}
}
}
}
if(flag) puts("Yes");
else puts("No");
}
return 0;
}
H
分析: 模拟暴力
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 1e6+11;
vector<int>ve;
void init(){
for(int i=1;i<N;i++){
if(i%5==0 ||i%3==0) {
ve.push_back(i);
if(ve.size()>100000+1) break;
}
}
}
int main(){
init();
//cout<<ve.size();
int n;
while(cin>>n){
cout<<ve[n-1]<<endl;
}
return 0;
}
I
分析:数据范围小,直接暴力就行。线段树区间查询+单点更新
哎,不难,但是没有时间写。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
#define LL long long
typedef pair<double,double>pii;
const int N = 2e5+11;
const int M = 1e6+11;
int mn[N<<2]; int val[N];
void Up(int o){
mn[o]=min(mn[o<<1],mn[o<<1|1]);
}
void Build(int o,int le,int ri){
if(le==ri){
scanf("%d",&val[le]);
mn[o]=val[le];
return ;
}
int mid=(le+ri)>>1;
Build(o<<1,le,mid);
Build(o<<1|1,mid+1,ri);
Up(o);
}
void Update(int o,int L,int R,int pos,int v){
if(L==R && L==pos) {
val[pos]=mn[o]=v;
return ;
}
int mid=(L+R)>>1;
if(pos<=mid) Update(o<<1,L,mid,pos,v);
else Update(o<<1|1,mid+1,R,pos,v);
Up(o);
}
int Query(int o,int L,int R,int le,int ri){
if(L==le &&R==ri )return mn[o];
int mid=(L+R)>>1;
if(ri<=mid) return Query(o<<1,L,mid,le,ri);
else if(le>mid) return Query(o<<1|1,mid+1,R,le,ri);
else {
return min(Query(o<<1,L,mid,le,mid),Query(o<<1|1,mid+1,R,mid+1,ri));
}
}
char s[N];
int tmp[N],z;
void get(char *str){ // 将字符串中数字逐一提取出来存到数组中。
z=0; int len=strlen(str);
int i=0;
while(str[i]!='(') i++;
while(1){
int x=0; int j;
for( j=i+1;str[j]>='0' && str[j]<='9';j++) x=x*10+str[j]-'0';
tmp[z++]=x;
i=j;
if(i>=len-1) break;
}
// for(int i=0;i<z;i++) printf("%d ",tmp[i]); puts("");
}
int main(){
int n,q;scanf("%d%d",&n,&q);
Build(1,1,n);
while(q--){
scanf("%s",s); get(s);
if(s[0]=='q') {
printf("%d\n",Query(1,1,n,tmp[0],tmp[1]));
}else{
// sort(tmp,tmp+z);
int en=val[tmp[0]];
for(int i=0;i<z-1;i++) Update(1,1,n,tmp[i],val[tmp[i+1]]);
Update(1,1,n,tmp[z-1],en);
}
}
return 0;
}
J
分析:找规律
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 1000+11;
int main(){
LL n;
while(cin>>n){
if(n==0) break;
if(n&1) puts("Bob");
else puts("Alice");
}
return 0;
}
K
分析: 卡这道题目卡半天。找半天才找到规律。因为我们可以发现 不论他们怎么减都将会是 gcd (x1,x2,…..) 的倍数。
代码
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<algorithm>
#include<stack>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int N = 1e5+11;
const int M = 2e5+11;
const int inf = 0x3f3f3f3f;
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int A[N];
int main() {
int n;
while(cin>>n){
scanf("%d",&A[0]); int ans=A[0];
for(int i=1;i<n;i++){
scanf("%d",&A[i]);
ans=gcd(ans,A[i]);
}
sort(A,A+n);
ans=A[n-1]/ans -n;
if(ans&1) puts("Alice");
else puts("Bob");
}
return 0;
}
L
分析:我们可以发现 ,只要找到枚举多边形的所有边,找到点P到这些边的最长距离和最短距离就可以了。
理论ac,几何题写的烦人,没有补 代码。