我的作用:增加罚时。 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; } }
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); } } }
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 ",dp[0]-1); } }
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(); } }
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; } } }
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 ",ans); } return 0; }
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 ",num/2-Bf(S)); } return 0; }
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 ",ans); break; } } if (flag) break; } } return 0; }
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; }
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); } } } }
L:
都到K题了你还不满足???你个贪得无厌的男人!树上dp是不可能碰的,数据结构啥的都不会,dp啥的也都不会,那岂不是负负得正!!!
这次随机大乱斗体验还不错,队友都太强了,希望以后可以多抱大腿,同时也提醒了我 书 的重要性。 溜了溜了(今天还没正式开始以后就9点到10点全在实验室了。。。)
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 ",ans); } return0; }