Gym 100712

我的作用:增加罚时。 noip380分大佬全程带飞出了10T,可惜被我搞的罚时太高了。。。

那啥,你会发现java代码有两种风格,嗯两个人,c++自然就是自招大佬了。。。

A:大水题略

B:(不是我写的。。。而且我还没看,,,对这种题一点兴趣没有

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while (T-- > 0) {
            int n = sc.nextInt();
            char[] a = sc.next().toCharArray();
            int t1[][] = me('P', 'S', 'R', n, a);//r
            int t2[][] = me('S', 'R', 'P', n, a);//p
            int t3[][] = me('R', 'P', 'S', n, a);//s
            int tt1[][] = mee('P', 'S', 'R', n, a);//r
            int tt2[][] = mee('S', 'R', 'P', n, a);//p
            int tt3[][] = mee('R', 'P', 'S', n, a);//s
            long ans = 0;
            for (int i = 0; i <= n; i++) {
                for (int j = 0; j <= n - i; j++) {
                    int x1, x2, x3;
                    if (i - 1 >= 0) {
                        x1 = t1[0][i - 1];
                    } else {
                        x1 = 0;
                    }
                    if (i <= n - 1) {
                        if (j - 1 >= 0) {
                            x2 = t2[i][i + j - 1];
                        } else {
                            x2 = 0;
                        }
                    } else {
                        x2 = 0;
                    }
                    if (i + j <= n - 1) {
                        x3 = t3[i + j][n - 1];
                    } else {
                        x3 = 0;
                    }

                    int xx1, xx2, xx3;
                    if (i - 1 >= 0) {
                        xx1 = tt1[0][i - 1];
                    } else {
                        xx1 = 0;
                    }
                    if (i <= n - 1) {
                        if (j - 1 >= 0) {
                            xx2 = tt2[i][i + j - 1];
                        } else {
                            xx2 = 0;
                        }
                    } else {
                        xx2 = 0;
                    }
                    if (i + j <= n - 1) {
                        xx3 = tt3[i + j][n - 1];
                    } else {
                        xx3 = 0;
                    }


                    if ((x1 + x2 + x3) < (xx1 + xx2 + xx3)) {
                        ans++;
                    }
                }
            }

            System.out.println(ans);


        }
    }

    static int[][] me(char a, char b, char c, int n, char[] aa) {
        int t1[][] = new int[n][n];
        for (int i = 0; i < n; i++) {
            int cnt = 0;
            for (int j = i; j < n; j++) {
                if (aa[j] == a) {
                    cnt++;
                }
                t1[i][j] = cnt;
            }
        }
        return t1;
    }

    static int[][] mee(char a, char b, char c, int n, char[] aa) {
        int t1[][] = new int[n][n];
        for (int i = 0; i < n; i++) {
            int cnt = 0;
            for (int j = i; j < n; j++) {
                if (aa[j] == b) {
                    cnt++;
                }
                t1[i][j] = cnt;
            }
        }
        return t1;
    }


}
View Code

C:大水题

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            int n = sc.nextInt();
            char[] s = sc.next().toCharArray();
            char[] a = new char[n];
            for (int i = 0; i < n; i++) {
                if (s[i] == '*') {
                    a[i] = '*';
                    if (i - 1 >= 0) {
                        a[i - 1] = '*';
                    }
                    if (i + 1 < n) {
                        a[i + 1] = '*';
                    }
                }
            }
            int x = 0;
            double ans = 0;
            for (int i = 0; i < n; i++) {
                if (a[i] != '*') {
                    x++;
                } else {
                    ans += Math.ceil(x / 3.0);
                    x = 0;
                }
            }
            ans += Math.ceil(x / 3.0);
            System.out.println((int)ans);
        }
    }
}
View Code

D:有官方题解,还是比较好懂的,这个是我照着题解写的。。。

注意dp指的是区间的个数,所以最后要减1.

#include <bits/stdc++.h>
using namespace std;

int t;
char s[100005];
int dp[100005];//分区
int main(){
    scanf("%d",&t);
    int l,k;
    while (t--){
        scanf("%d%d",&l,&k);
        scanf("%s",&s);
        memset(dp,0, sizeof(dp));
        dp[l]=0;
        for(int i = l-1;i>=0;--i){
            bool isAlter = true;
            dp[i] = 1e9;
            for(int j=i;j-i+1<=k&&j<l;j++){
                if (j>i&&s[j]==s[j-1]){
                    isAlter = false;
                }
                if (i==j||!isAlter){
                    dp[i] = min(dp[i],1+dp[j+1]);
                }
            }
        }
        printf("%d\n",dp[0]-1);
    }
}
View Code

E:大水题

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {
    static BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer tok;
    static boolean hasNext()
    {
        while(tok==null||!tok.hasMoreTokens())
            try{
                tok=new StringTokenizer(in.readLine());
            }
            catch(Exception e){
                return false;
            }
        return true;
    }
    static String next()
    {
        hasNext();
        return tok.nextToken();
    }
    static long nextLong()
    {
        return Long.parseLong(next());
    }
    static int nextInt()
    {
        return Integer.parseInt(next());
    }
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) {
        int t = nextInt();
        while (t--!=0){
            int n = nextInt();
            int a[] = new int[n];
            int max = 0;
            for(int i=0;i<n;i++) {
                a[i] = nextInt();
                max = a[i] > max ? a[i] : max;
            }
            int temp = 100-max;
            int num = 0;
            for(int i=0;i<n;i++){
                if (a[i]+temp>=50){
                    num++;
                }
            }
            out.println(num);
        }
        out.flush();
    }
}
View Code

F:最小生成树板子题。(归排很辣眼睛,队友说java自带的排序就很好,nlogn,好像还真是。。。可是又有人说那是n方的,,我很迷茫

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {//最小生成树
    static int n;//点的个数
    static int m;//无向边的个数
    static Graph graph[];

    static int fa[];
    static int rank[];

    static int ans;
    public static void main(String args []) {
        int t = nextInt();
        while (t--!=0){
        n = nextInt();
        m = nextInt();
        if (m==0){
            out.println("0");
            out.flush();
            continue;
        }
        fa = new int[100010];
        rank = new int[100010];
        for (int i=1;i<=100000;i++){
            fa[i]=i;
            rank[i]=0;
        }
        ans = 0;
        graph = new Graph[m];
        for (int p=0;p<m;p++){
            int st = nextInt();
            int end = nextInt();
            int w = nextInt();
            graph[p] = new Graph(st,end,w);
        }
        graph = mergeSort(graph);
        int i=0;
        int num=0;
        while (num<n-1){
            if (same(graph[i].st,graph[i].end)){//在一起
                i++;
            }
            else {
                unite(graph[i].st,graph[i].end);
                num++;
                ans=ans>graph[i].w?ans:graph[i].w;
            }
        }
        out.println(ans);
        out.flush();
        }
    }

    public static int find(int a){
        if (a==fa[a]){
            return a;
        }
        else {
            return fa[a] = find(fa[a]);
        }
    }

    public static void unite(int x,int y){
        x = find(x);
        y = find(y);
        if (x==y)return;
        if (rank[x]<rank[y]){
            fa[x] = y;
        }else {
            fa[y]=x;
            if (rank[x]==rank[y]) rank[x]++;
        }
    }

    public static boolean same(int x,int y){
        return find(x)==find(y);
    }

    public static Graph [] mergeSort(Graph a[]) {
        return merge(a,0,a.length-1);
    }
    public static Graph [] merge(Graph a[],int start,int end) {
        int mid = (start+end)/2;
        if(start==end)
            return new Graph[] {a[start]};
        else {
            return guibing(merge(a,start,mid),merge(a,mid+1,end));
        }
    }
    public static Graph [] guibing(Graph a[],Graph b[]){
        int n = a.length+b.length;
        Graph c[] = new Graph[n];
        int i=0;int j=0;int s = 0;
        while(i<a.length&&j<b.length){
            if(a[i].w<b[j].w){
                c[s++]=a[i++];
            }
            if(i<a.length&&a[i].w>b[j].w){
                c[s++]=b[j++];
            }
            if(j<b.length&&i<a.length&&a[i].w==b[j].w) {
                c[s++]=a[i++];
                c[s++]=b[j++];
            }
        }
        while(i<a.length)
            c[s++]=a[i++];
        while(j<b.length)
            c[s++]=b[j++];
        return c;
    }

    static BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer tok;
    static boolean hasNext()
    {
        while(tok==null||!tok.hasMoreTokens())
            try{
                tok=new StringTokenizer(in.readLine());
            }
            catch(Exception e){
                return false;
            }
        return true;
    }
    static String next()
    {
        hasNext();
        return tok.nextToken();
    }
    static long nextLong()
    {
        return Long.parseLong(next());
    }
    static int nextInt()
    {
        return Integer.parseInt(next());
    }
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));

    static class Graph {
        int st;
        int end;
        int w;

        public Graph(int a, int b, int c) {
            st = a;
            end = b;
            w = c;
        }
    }
}
View Code

G:我是傻逼! 我非要贪心wa了三发。。。我是傻逼!!!直接搜就完事了。。。(顺便问下问啥不能贪心啊,求前缀和,然后再求能扔出去几个,257第一遍搜了三个,第二遍把2扔出去)(我跟大佬说了题意然后一瞬间写完了。。。)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int T,n,s,a[11],ans;
int cmp(int x,int y){
    return x>y;
}
void Dfs(int now,int sum,int cnt){
    if(sum>=s){
        ans=max(ans,cnt);return;
    }
    if(now==n+1){
        if(sum>=s)ans=max(ans,cnt);
        return;
    }
    Dfs(now+1,sum+a[now],cnt+1);
    Dfs(now+1,sum,cnt);
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&s);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+1+n,cmp);
        ans=0;Dfs(1,0,0);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

H:我没看,tarjan缩点好像是?就最近codeforce有一场contest有一道题就是tarjan缩点,不妨自己找一下(我只想快点回宿舍洗澡)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define maxn 200010
using namespace std;
int T,n,m,num,head[maxn],dfn[maxn],low[maxn];
int s[maxn],top,f[maxn],topt,bl[maxn];
int Head[maxn],N;
queue<int>q;
struct node{
    int v,pre;
}e[maxn],p[maxn];
int init(){
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
void Memset(){
    memset(head,0,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(s,0,sizeof(s));
    memset(f,0,sizeof(f));
    memset(bl,0,sizeof(bl));
    memset(Head,0,sizeof(Head));
    N=0;num=0;top=0;topt=0;N=0;
}
void Add(int from,int to){
    num++;e[num].v=to;
    e[num].pre=head[from];
    head[from]=num;
}
void Ad(int from,int to){
    num++;p[num].v=to;
    p[num].pre=Head[from];
    Head[from]=num;
}
void Tarjan(int u,int from){
    dfn[u]=low[u]=++topt;
    s[++top]=u;f[u]=1;
    for(int i=head[u];i;i=e[i].pre){
        int v=e[i].v;
        if(v==from)continue; 
        if(dfn[v]==0){
            Tarjan(v,u);low[u]=min(low[u],low[v]);
        }
        else if(f[v])low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u]){
        N++;while(s[top]!=u){
            f[s[top]]=0;bl[s[top]]=N;top--;
        }
        f[s[top]]=0;bl[s[top]]=N;top--;
    }
}
int Bfs(int S){
    memset(f,0,sizeof(f));
    memset(s,0,sizeof(s));
    f[S]=1;q.push(S);
    while(!q.empty()){
        int k=q.front();q.pop();
        for(int i=Head[k];i;i=p[i].pre){
            int v=p[i].v;
            if(f[v])continue;
            f[v]=1;q.push(v);s[v]=s[k]+1;
        }
    }
    int mx=0,V=S;
    for(int i=1;i<=N;i++)
        if(mx<s[i]){
            mx=s[i];V=i;
        }
    return V;
}
int Bf(int S){
    memset(f,0,sizeof(f));
    memset(s,0,sizeof(s));
    f[S]=1;q.push(S);
    while(!q.empty()){
        int k=q.front();q.pop();
        for(int i=Head[k];i;i=p[i].pre){
            int v=p[i].v;
            if(f[v])continue;
            f[v]=1;q.push(v);s[v]=s[k]+1;
        }
    }
    int mx=0;
    for(int i=1;i<=N;i++)
        mx=max(mx,s[i]);
    return mx;
}
int main(){
    T=init();
    while(T--){
        n=init();m=init();int u,v;
        Memset();
        for(int i=1;i<=m;i++){
            u=init();v=init();
            Add(u,v);Add(v,u);
        }
        for(int i=1;i<=n;i++)
            if(dfn[i]==0)Tarjan(i,0);
        num=0;for(u=1;u<=n;u++)
            for(int i=head[u];i;i=e[i].pre){
                v=e[i].v;
                if(bl[u]==bl[v])continue;
                Ad(bl[u],bl[v]);
            }
        int S=Bfs(1);
        printf("%d\n",num/2-Bf(S));
    }
    return 0;
}
View Code

I: 和  挑战程序设计 上一道农夫挤牛奶(区间反转)很像,关键是优化的思想!!(我说我的队友一直在看那本书。。。)优化真的挺难懂。

#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
int num[256];
char s[256];
int t;
int main(){
    scanf("%d",&t);
    while (t--){
        scanf("%s",s);
        int n = strlen(s);
        for(int i=0;i<n;i++){
            num[i] = s[i]-'0';
        }
        int ans ;
        for(ans = n;ans>=1;ans--){//枚举区间
            int flag;
            for(int k=0;k<10;k++){//枚举要变成的值
                int sum = 0,change[256]={0};
                for(int i=0;i<n-(ans-1);i++){//后面的转不了
                    if(i-ans>=0){
                        sum-=change[i-ans];
                    }
                    change[i]=((k+10)-(num[i]+sum)%10)%10;
                    sum+=change[i];
                }
                flag=1;
                for(int i=n-(ans-1);i<n;i++){
                    if(i-ans>=0){
                        sum-=change[i-ans];
                    }
                    change[i]=((k+10)-(num[i]+sum)%10)%10;
                    if(change[i]!=0){
                        flag = 0;
                        break;
                    }
                }
                if (flag){
                    printf("%d\n",ans);
                    break;
                }
            }
            if (flag)
                break;
        }
    }
    return 0;
}
View Code

J:这个题我wa了,很玄学,然后我的队友用我的思路写了一发ac了。。。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while (T-- > 0) {
            int n = sc.nextInt();
            int k =sc.nextInt();
            int a [] = new int[99];
            int b [] = new int[99];
            for(int i = 0 ; i < n ; i ++){
                a[sc.nextInt()]++;
            }
            for(int i = 0 ; i < k ; i ++){
                b[sc.nextInt()]++;
            }
            int j=0;
            for(int i = 0 ; i <20;i++){
                if(a[i]>0) {
                    j++;
                    for (; j < 60; j++) {
                        if(b[j]>=a[i]){
                            break;
                        }
                    }
                }
            }
            System.out.println(j>52?"NO":"YES");
        }
    }
}
class A{
    boolean f;
    int n;
}
View Code

K;没看,好像是个水题?

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while (T-- > 0) {
            int n = sc.nextInt();
            int k =sc.nextInt();
            int a[] = new int[n];
            int b[] = new int[100010];
            for(int i = 0 ; i< n;i++){
                int t = sc.nextInt();
                b[t]++;
            }
            boolean yes= false;
            for(int i = 1 ; i <= k;i++){
                if(b[i]>0&&k%i==0){
                    if((b[k/i])>0){
                        if(k/i==i&&b[i]<=1){
                            continue;
                        }
                        System.out.println(i+" "+k/i);
                        yes=true;
                        break;
                    }
                }
            }
            if(!yes){
                System.out.println(-1);
            }
        }
    }
}
View Code

L:

都到K题了你还不满足???你个贪得无厌的男人!树上dp是不可能碰的,数据结构啥的都不会,dp啥的也都不会,那岂不是负负得正!!!  

这次随机大乱斗体验还不错,队友都太强了,希望以后可以多抱大腿,同时也提醒了我 书 的重要性。  溜了溜了(今天还没正式开始以后就9点到10点全在实验室了。。。)

 

 

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>usingnamespacestd; int T,n,s,a[11],ans; int cmp(int x,int y){ return x>y; } void Dfs(int now,int sum,int cnt){ if(sum>=s){ ans=max(ans,cnt);return; } if(now==n+1){ if(sum>=s)ans=max(ans,cnt); return; } Dfs(now+1,sum+a[now],cnt+1); Dfs(now+1,sum,cnt); } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&s); for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n,cmp); ans=0;Dfs(1,0,0); printf("%d\n",ans); } return0; }

posted @ 2018-07-22 20:29  MXang  阅读(273)  评论(0编辑  收藏  举报