标签:des style blog http color os io for ar
A:要求是否全部的字符都挨着偶数个‘o‘,要读题啊....各种读错题...
#include <cstdio> using namespace std; char maz[101][101]; int n; int cnt[101][101]; const int dx[4]={0,0,-1,1}; const int dy[4]={1,-1,0,0}; int main(){ scanf("%d",&n); gets(maz[0]); for(int i=0;i<n;i++){ gets(maz[i]); } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(maz[i][j]==‘o‘){ for(int k=0;k<4;k++){ int nx=i+dx[k]; int ny=j+dy[k]; if(nx<n&&ny<n&&nx>=0&&ny>=0){cnt[nx][ny]++;} } } } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(cnt[i][j]&1){puts("NO");return 0;} } } puts("YES"); return 0; }
B:贪心,要读题啊!,数组开小了结果Bcha了,
#include <cstdio> #include <algorithm> using namespace std; long long n,k; long long cnt[26]; char maz[200001]; int main(){ scanf("%I64d%I64d",&n,&k); gets(maz); gets(maz); for(int i=0;i<n;i++)cnt[maz[i]-‘A‘]++; sort(cnt,cnt+26); long long ans=0; for(int i=25;i>=0;i--){ if(cnt[i]>=k){ ans+=k*k; k=0; } else { k-=cnt[i]; ans+=cnt[i]*cnt[i]; } if(k==0)break; } printf("%I64d\n",ans); return 0; }
C:
Appleman and Toastman play a game. Initially Appleman gives one group of n numbers to the Toastman, then they start to complete the following tasks:
After guys complete all the tasks they look at the score value. What is the maximum possible value of score they can get?
The first line contains a single integer n (1 ≤ n ≤ 3·105). The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106) — the initial group that is given to Toastman.
Print a single integer — the largest possible score.
3
3 1 5
26
1
10
10
题解意思:
这是一道霍夫曼编码的反问题,把所有边权取反就是霍夫曼树问题,详细证明请看算法导论,大概证明一下:
可以把每次的拿来拆分的每一段的都作为树上的节点,长度为1的值必然是叶节点,会在统计一次后被抛出,这时父节点权值则是子节点权值之和,而且必然是一颗二叉树,这与题目是符合的,也就是说深度越大的叶节点加和的次数越多,那么把最大的那两个节点先放在树里,那么它们的父节点就拥有两个节点之和的性质,那么再添加次大的,如此构建就形成了整棵最优树,(算法导论可以严格证明这是棵最优树,通过反证法),于是除了最大的两个点加了n次,其余的点分别加了n-1,n-2,....2次
#include <cstdio> #include <algorithm> using namespace std; const int maxn=300005; int n; long long a[maxn]; int main(){ scanf("%d",&n); long long ans=0,sum=0; for(int i=0;i<n;i++){scanf("%I64d",a+i);sum+=a[i];} sort(a,a+n); ans=sum; for(int i=1;i<n;i++){ ans+=sum; sum-=a[i-1]; } printf("%I64d\n",ans); return 0; }
D:
Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are colored white.
Consider a set consisting of k (0 ≤ k < n) edges of Appleman‘s tree. If Appleman deletes these edges from the tree, then it will split into(k + 1) parts. Note, that each part will be a tree with colored vertices.
Now Appleman wonders, what is the number of sets splitting the tree in such a way that each resulting part will have exactly one black vertex? Find this number modulo 1000000007 (109 + 7).
The first line contains an integer n (2 ≤ n ≤ 105) — the number of tree vertices.
The second line contains the description of the tree: n - 1 integers p0, p1, ..., pn - 2 (0 ≤ pi ≤ i). Where pi means that there is an edge connecting vertex (i + 1) of the tree and vertex pi. Consider tree vertices are numbered from 0 to n - 1.
The third line contains the description of the colors of the vertices: n integers x0, x1, ..., xn - 1 (xi is either 0 or 1). If xi is equal to 1, vertex i is colored black. Otherwise, vertex i is colored white.
Output a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).
3
0 0
0 1 1
2
6
0 1 1 0 4
1 1 0 0 1 0
1
10
0 1 2 1 4 4 4 0 8
0 0 0 1 0 1 1 0 0 1
27
这是一道树形dp,我一开始想到奇怪的地方去了,什么连通域之类的
对每个点,dp记录使其的所有子树成为单黑或纯白的方式,最后再加上自身的黑/白属性
具体来说
初始化:子树单黑=0,子树纯白=1
单黑=现有单黑*子树纯白+子树单黑*现有纯白
纯白=现有纯白*子树纯白
然后加入自身的属性
如果自身为黑,那么单黑=子树纯白(现有黑:切掉所有子节点成为0)
如果自身为白,那么纯白*=子树纯白(切掉本身使得孤立的方式更多)
#include<cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn=100005; const long long mod=1000000007 ; long long dp[maxn][2]; int color[maxn]; vector<int> G[maxn]; bool vis[maxn]; void dfs(int s){ dp[s][0]=1; dp[s][1]=0; vis[s]=true; for(int i=0;i<G[s].size();i++){ int t=G[s][i]; if(vis[t])continue; dfs(t); dp[s][1]=(dp[s][0]*dp[t][1]+dp[s][1]*dp[t][0])%mod; dp[s][0]=dp[s][0]*dp[t][0]%mod; } if(color[s]==1){ dp[s][1]=dp[s][0]; } else dp[s][0]+=dp[s][1]; dp[s][1]%=mod; dp[s][0]%=mod; } int main(){ int n; scanf("%d",&n); for(int i=1;i<n;i++){ int temp; scanf("%d",&temp); G[temp].push_back(i); } for(int i=0;i<n;i++)scanf("%d",color+i); dfs(0); printf("%I64d\n",dp[0][1]); return 0; }
E:
Appleman has a very big sheet of paper. This sheet has a form of rectangle with dimensions 1 × n. Your task is help Appleman with folding of such a sheet. Actually, you need to perform q queries. Each query will have one of the following types:
Please look at the explanation of the first test example for better understanding of the problem.
The first line contains two integers: n and q (1 ≤ n ≤ 105; 1 ≤ q ≤ 105) — the width of the paper and the number of queries.
Each of the following q lines contains one of the described queries in the following format:
For each query of the second type, output the answer.
7 4
1 3
1 2
2 0 1
2 1 2
4
3
10 9
2 2 9
1 1
2 0 1
1 8
2 0 8
1 2
2 1 3
1 4
2 2 4
7
2
10
4
5
翻折,当长度>len/2的时候那么就反向翻折,这时候相当于反向了一次,需要反着来统计
看上去思路很清晰但是很麻烦
#include<cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn=100005; const int maxnode=400005; long long w[maxnode]; int cur,s,e,len,n,q; int num(int i){//返回正确的标号,传入的是从开始的端点所需经过距离 if(cur==0){return s+i;} return e-i; } void update(int k,int d){//更新线段树 int tk=k; k+=n-1; w[k]+=d; while(k>0){ k=(k-1)/2; w[k]+=d; } } void inv(int l){//翻转 int tl; if(l*2>len){tl=len-l;cur^=1;}//翻转统计的同时就要反向更新了 else tl=l; for(int i=0;i<tl;i++){ int td=num(tl*2-1-i); int td2=num(i); update(td,w[td2+n-1]); update(td2,-w[td2+n-1]); } if(cur)e-=tl;else s+=tl; len=e-s+1; } long long query(int a,int b,int k,int l,int r){ if(r<=a||l>=b||l>=r)return 0; if(a<=l&&r<=b){ return w[k]; } else { long long v1=query(a,b,k*2+1,l,(l+r)/2); long long v2=query(a,b,k*2+2,(l+r)/2,r); return v1+v2; } } int main(){ scanf("%d%d",&n,&q);int tn=n,ttn=n;n=1; while(tn>0){n<<=1;tn>>=1;} for(int i=0;i<ttn;i++)update(i,1); s=0;e=ttn-1;len=ttn; while(q--){ int op; scanf("%d",&op); if(op==1){ int l; scanf("%d",&l); inv(l); } else{ int l,r; scanf("%d%d",&l,&r); if(cur){ l=num(l-1);//这里卡我半天因为题目给的是从s开始的序号所以从e开始就要+1,传进的参数要-1 r=num(r-1); } else { l=num(l); r=num(r); } if(l>r)swap(l,r); long long ans=query(l,r,0,0,n); printf("%I64d\n",ans); } } }
标签:des style blog http color os io for ar
原文地址:http://www.cnblogs.com/xuesu/p/3940760.html