【HPU16级积分赛(二)】

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,几何题写的烦人,没有补 代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值