D二叉树的中序遍历
看似复杂……实则水题;
在纸上画画,发现不满足题意的情况只有一种:##连在一起。其他情况有至少有一种途径可以构造出一颗满足题意的二叉树。但是可能做比赛的时候怕会有坑。。。但实际上真的就是这么简单。。
/* *********************************************** Author :angon ************************************************ */ #include <stdio.h> char s[maxn]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t; scan(t); while(t--) { scanf("%s",s); int len=strlen(s); int flag=1; for(int i=0;i<len;i++) { if(s[i]=='#'&&s[i+1]=='#') { printf("no\n"); flag=0; break; } } if(flag) printf("yes\n"); } return 0; }
吐槽:题目介绍说没有空格,但是实际上有空格,无端wa一次!
/* *********************************************** Author :angon ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <stack> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; #define REP(i,k,n) for(int i=k;i<n;i++) #define REPP(i,k,n) for(int i=k;i<=n;i++) #define scan(d) scanf("%d",&d) #define scann(n,m) scanf("%d%d",&n,&m) #define LL long long #define maxn 1005 #define mod 100000007 /* inline int read() { int s=0; char ch=getchar(); for(; ch<'0'||ch>'9'; ch=getchar()); for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0'; return s; } inline void print(int x) { if(!x)return; print(x/10); putchar(x%10+'0'); } */ int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); char s[3000]; int t; scan(t); getchar(); while(t--) { gets(s); int len=strlen(s); int c[30]; memset(c,0,sizeof(c)); for(int i=1;i<len;i+=3) { if(c[s[i]-97]==0) c[s[i]-97]++; } int ans=0; for(int i=0;i<=26;i++) { if(c[i]) ans++; } printf("%d\n",ans); } return 0; }E 积木积水
一道很不错的思维题,不需要任何算法,但实际上并没有那么好想。
一旦发现了这个性质就变得非常简单:找到最长的那个柱子,在水满的情况下,从前往后,在它左边水面是非递减的,右边是非递增的(如果从最后一个柱子往中看也是非递减的)
有了这个性质,那么只要从左右各扫一次就可以了;
/* *********************************************** Author :angon ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <stack> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; #define REP(i,k,n) for(int i=k;i<n;i++) #define REPP(i,k,n) for(int i=k;i<=n;i++) #define scan(d) scanf("%d",&d) #define scann(n,m) scanf("%d%d",&n,&m) #define mst(a,k) memset(a,k,sizeof(a)); #define LL long long #define maxn 1000005 #define mod 100000007 /* inline int read() { int s=0; char ch=getchar(); for(; ch<'0'||ch>'9'; ch=getchar()); for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0'; return s; } inline void print(int x) { if(!x)return; print(x/10); putchar(x%10+'0'); } */ int a[maxn]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,t; scan(t); while(t--) { scan(n); int maxc=-1,idx; REP(i,0,n) { scan(a[i]); if(a[i]>maxc) { maxc=a[i]; idx=i; } } LL sum=0; int last=a[0];//last表示当前最长的柱子 REP(i,1,idx) { if(a[i]<=last)//如果比它短就加上 sum+=(last-a[i]); else //否则更新last last=a[i]; } last=a[n-1]; for(int i=n-1;i>idx;i--) { if(a[i]<=last) sum+=(last-a[i]); else last=a[i]; } printf("%lld\n",sum); } return 0; }
容斥 加 dfs枚举子集;
容斥:减去每个数倍数的个数,再把重复减去的加回来;为了达到这个目的:枚举所有子集,子集元素个数奇数的res-=1e9/lcm;
元素个数为偶数的 res+=1e9/lcm;
剪枝:lcm > 1e9 直接return;
优化:1 去重, 2 如果a[i]%a[j]==0,把a[i]去掉;
为什么不会爆:
虽然n<=50 ,子集个数为 2^50-1,但是a[i]<=1000;因为优化2,所以最多就是50个没有直接倍数关系的数,这样必然导致相当一部分a[i]会比较大,这样在剪枝的时候就可以很容易的剪去,
/* *********************************************** Author :angon ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <stack> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; #define REP(i,k,n) for(int i=k;i<n;i++) #define REPP(i,k,n) for(int i=k;i<=n;i++) #define scan(d) scanf("%d",&d) #define scann(n,m) scanf("%d%d",&n,&m) #define mst(a,k) memset(a,k,sizeof(a)); #define LL long long #define maxn 1005 #define N 1000000000 /* inline int read() { int s=0; char ch=getchar(); for(; ch<'0'||ch>'9'; ch=getchar()); for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0'; return s; } inline void print(int x) { if(!x)return; print(x/10); putchar(x%10+'0'); } */ int cnt,a[55],vis[55]; LL ret; LL gcd(LL a,LL b) { return a%b==0?b:gcd(b,a%b); } LL lcm(LL a,LL b) { return a/gcd(a,b)*b; } void dfs(int num,int f, LL tmp) { if(tmp > N ) return ; if(num == cnt) { if(f&1) ret -= (N/tmp); else ret += (N/tmp); return ; } dfs(num+1,f,tmp); dfs(num+1,f+1,lcm(a[num],tmp)); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,n; scan(t); while(t--) { scan(n); REP(i,0,n) scan(a[i]); mst(vis,0); sort(a,a+n); for(int i=0;i<n;i++){ if(vis[i]) continue; for(int j=i+1;j<n;j++){ if(a[j]%a[i]==0) vis[j]=1; } } cnt=0; REP(i,0,n) if(vis[i]==0) a[cnt++]=a[i]; ret=0; dfs(0,0,1LL); printf("%lld\n",ret); } return 0; }