您的位置:首页 > 产品设计 > UI/UE

UESTC 2016 Summer Training #5 Div.2(未完待续)

2016-07-15 18:54 691 查看
A

#include <cstdio>
#include <cstring>
#include <vector>
#define MAXN 100005
#define mem(a) memset(a, 0, sizeof(a))
using namespace std;

int TreeArray[MAXN], Left[MAXN], Right[MAXN], Fork[MAXN];
typedef vector<int> Ve;
vector<Ve>Edge(MAXN);
int N,M;
int key;

void init()//初始化数组和
{
mem(Left);  mem(Right);
mem(Fork);  mem(TreeArray);
for(int i=0;i<MAXN;i++)Edge[i].clear();
}

void DFS(int node)//为每一个node添加一个左值和右值,表示这个节点所
{
Left[node] = key;
for(int i=0;i<Edge[node].size();i++)
{
key+=1;
DFS(Edge[node][i]);
}
Right[node] = key;
}

int LowBit(int x)//返回的是2^k
{
return x & (x ^ (x-1));
}

void Edit(int k, int num)//修改节点k,如果是添加一个,代入1,删除一个代入-1
{
while(k <= N)
{
TreeArray[k] += num;
k += LowBit(k);
}
}

int GetSum(int k)//得到1...k的和
{
int sum = 0;
while(k>=1)
{
sum += TreeArray[k];
k -= LowBit(k);
}
return sum;
}

void ReadDataAndDo()
{
int a,b;
char ch;
for(int i=1;i<N;i++)//输入a,b把边存放在容器里面
{
scanf("%d%d", &a, &b);
Edge[a].push_back(b);
}
key = 1;    DFS(1);//为每一个节点对应一个左边界和右边界,他自己就存放在左边界里面,而它的管辖范围就是左边界到右边界
for(int i=1;i<=N;i++)
{
Fork[i] = 1;//最初每个Fork上都有一个苹果
Edit(i,1);//同时更新树状数组的值
}
scanf("%d%*c", &M);
for(int i=0;i<M;i++)
{
scanf("%c %d%*c", &ch, &b);
if(ch == 'Q')//b的子树就是[Left[b], right[b]]
{
printf("%d\n", GetSum(Right[b]) - GetSum(Left[b]-1));
}
else
{
if(Fork[b]) Edit(Left[b],-1);//由于每个节点的编号就是它的左值,所以直接修改左节点
else Edit(Left[b],1);
Fork[b] = !Fork[b];//变为相反的状态
}
}
}

int main()
{
while(~scanf("%d", &N))
{
init();
ReadDataAndDo();
}
return 0;
}


B

#include <bits/stdc++.h>
using namespace std;
int n,q,x;
int main(){
int a=0,b=0;
scanf("%d%d",&n,&q);
while(q--){
int tmp;
scanf("%d",&tmp);
if(tmp==1){
scanf("%d",&x);
a = (n+a-x)%n;
b = (n+b-x)%n;
if(x%2) swap(a,b); //当x为奇数时,1,2的位置奇偶性必然改变成相反的
}else{
a = (a+n-1)%n;
b = (b+n+1)%n;
swap(a,b);//交换奇偶位置
}
}
for(int i=1; i<=n; i++){
if(i%2) printf("%d ",(a+i-1+n)%n+1);//用1的位置递推所有奇数位置的编号
else printf("%d ",(b+i-1+n)%n+1); //用2的位置递推所有偶数位置的编号
}
return 0;
}


C

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>

#define INF 0x3f3f3f3f
#define eps 1e-6

typedef long long LL;
const double pi = acos(-1.0);
const long long Mod = INF;
using namespace std;

int main()
{
LL M,N;
cin >> N >> M;
LL k = 2;
LL a = N / M;
printf("%I64d",a);
N = (N - a * M) * k;
while(N)
{
a = N / M;
printf(" %I64d",a);
k++;
N = (N - a * M) * k;
}
puts("");
return 0;
}


D

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>

#define INF 0x3f3f3f3f
#define eps 1e-6

typedef long long LL;
const double pi = acos(-1.0);
const long long MOD = 1e9 + 7;
using namespace std;

struct node
{
int u,v,w;
}edge[10005];

int dis[10005];

int top;

int fun(int N)
{
int u,v,w;
for(int i = 1;i <= N;i++)
dis[i] = INF;
dis[1] = 0;
for(int k = 0;k < N - 1;k++)
for(int i = 0;i < top;i++)
{
u = edge[i].u;
v = edge[i].v;
w = edge[i].w;
if(dis[u] + w < dis[v] && dis[u] < INF)
dis[v] = dis[u] + w;
}
for(int i = 0;i < top;i++)
{
u = edge[i].u;
v = edge[i].v;
w = edge[i].w;
if(dis[u] + w < dis[v] && dis[u] < INF)
return 0;
}
return 1;
}

void add(int u,int v,int w)
{
edge[top].u = u;
edge[top].v = v;
edge[top++].w = w;
}

int main()
{
int F,N,M,W,T,S,E;
cin >> F;
while(F--)
{
top = 0;
cin >> N >> M >> W;
for(int i = 0;i < M;i++)
{
cin >> S >> E >> T;
add(S,E,T);
add(E,S,T);
}
for(int i = 0;i < W;i++)
{
cin >> S >> E >> T;
add(S,E,-T);
}
if(!fun(N))
puts("YES");
else
puts("NO");
}
return 0;
}


E

题目大意:

妈妈烧了M根骨头分给n个孩子们,第i个孩子有两个参数Mini和Maxi,分别表示这个孩子至少要得到Mini根骨头,至多得到Maxi根骨头。

输出一个整数,表示妈妈有多少种分配方案(骨头不能浪费,必须都分给孩子们)。

思路:

所以我们可以通过换元法,让下界的限制变成得到简单形式。

但是很遗憾的是,对于上界的限制,我们无法直接计算出答案。

逆向思维

于是根据容斥原理来做有:

import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main {
public static void main(String args[]) throws Exception {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
Task solver = new Task();
solver.main(in, out);
out.close();
}
}

class InputReader {
BufferedReader reader;
StringTokenizer tokenizer;

public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream));
tokenizer = null;
}

public String next() {
if (!hasNext())
throw new RuntimeException();
return tokenizer.nextToken();
}

boolean hasNext() {
while (tokenizer == null || !tokenizer.hasMoreTokens())
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (Exception e) {
return false;
}
return true;
}

public long nextLong() {
return Long.parseLong(next());
}

public int nextInt() {
return Integer.parseInt(next());
}
}

class Task {
BigInteger zero = BigInteger.ZERO;
BigInteger one = BigInteger.ONE;
BigInteger ten = BigInteger.TEN;
final int maxn = 50005;
BigInteger[] f=new BigInteger[maxn];
int[] A=new int [15];
int[] B=new int [15];
int n,m;
BigInteger ans;
BigInteger C(int n,int m)
{
if(m>n)
return zero;
m=Math.min(m, n-m);
BigInteger res=one;
for(int i=n;i>=n-m+1;--i)
{
res=res.multiply(BigInteger.valueOf(i)).divide(BigInteger.valueOf(n-i+1));
}
return res;
}
void gao(int x,int cnt,int remain)
{
if(x<0)
{
if((cnt&1)>0)
ans=ans.subtract(C(remain+n-1,n-1));
else
ans=ans.add(C(remain+n-1,n-1));
return;
}
gao(x-1,cnt,remain);
if(remain>B[x])
gao(x-1,cnt+1,remain-B[x]-1);
}
void main(InputReader in, PrintWriter out) throws Exception {
int i,j;
ans=zero;
int T;
T=in.nextInt();
for(int cas=0;cas<T;++cas)
{
ans=zero;
n=in.nextInt();
m=in.nextInt();
for(i=0;i<n;++i)
{
A[i]=in.nextInt();
B[i]=in.nextInt();
m-=A[i];
B[i]-=A[i];
}
if(m<0)
{
out.println(0);
}
else if(m==0)
{
out.println(1);
}
else
{
gao(n-1,0,m);
out.println(ans);
}
}
}
}


F

题意:给你一个数N,让你用前N个数,通过N-1次加减乘除运算得到24。让你输出合法的计算过程。

做法:

当N<4时,很显然,无法得到24点;

当N>=4时,可以得到24点,这时,我们分成两种情况进行构造。

1)当N为偶数时,由1,2,3,4显然可以构造出24,剩下的N-4(偶数)个数只需两两相减,并最后与24相乘即可。

2)当N为奇数时,由1,2,3,4,5显然可以构造出24,剩下的N-5(偶数)个数只需两两相减,并最后与24相乘即可。具体实现方法见代码。

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>

#define INF 0x3f3f3f3f
#define eps 1e-6

typedef long long LL;
const double pi = acos(-1.0);
const long long MOD = 1e9 + 7;
using namespace std;

int a[12] = {0};

int main()
{
int N;
cin >> N;
int ok = 1;
if(N < 4)
{
puts("NO");
return 0;
}
else
puts("YES");
if(N % 2 == 0)
{
printf("2 * 3 = 6\n");
printf("4 * 6 = 24\n");
printf("24 * 1 = 24\n");
for(int i = 5;i < N;i += 2)
{
printf("%d - %d = 1\n",i + 1,i);
printf("24 * 1 = 24\n");
}
}
else
{
printf("4 * 5 = 20\n");
printf("20 + 3 = 23\n");
printf("23 + 2 = 25\n");
printf("25 - 1 = 24\n");
for(int i = 6;i < N;i += 2)
{
printf("%d - %d = 1\n",i + 1,i);
printf("24 * 1 = 24\n");
}
}
return 0;
}


G

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define esp 0.00000000001
const int N=2e5+10,M=1e6+10,inf=1e9;
#define mem(s) memset(s,0,sizeof(s))
int n,m,head
,t,vis
,deep
,fa
[20];
int a
;
int flag
;
struct ss {
int to,next;
}e[N*2];
void add(int u,int v) {
e[t].next=head[u];e[t].to=v;head[u]=t++;
}
void init() {
t=1;mem(head);mem(vis);mem(fa);mem(deep);mem(flag);
}
void dfs(int x) {
vis[x]=1;
for (int i=1; i<=18 ;i++) {
if(deep[x]<(1<<i)) break;
fa[x][i] = fa[fa[x][i-1]][i-1];
}
for (int i=head[x];i;i=e[i].next) {
if(vis[e[i].to]) continue;
deep[e[i].to]=deep[x]+1;
fa[e[i].to][0]=x;
dfs(e[i].to);
}
}
int RMQ_LCA(int x,int y) {
if(deep[x]<deep[y]) swap(x,y);
int d=deep[x]-deep[y];
for (int i=0; i<=18 ;i++)
if((1<<i)&d) x=fa[x][i];
for (int i=18; i>=0 ;i--) {
if(fa[x][i]!=fa[y][i]) {
x=fa[x][i];y=fa[y][i];
}
}
if(x==y) return x;
else return fa[x][0];
}
int Dis_LCA(int x,int y) {
int LCA= RMQ_LCA(x,y);
return (deep[x]+deep[y]-2*deep[LCA]);
}
struct is
{
int pos,step,pre;
};
int main()
{
int x,y,z,i,t;
while(~scanf("%d",&x))
{
queue<is>q;
init();
for(i=2;i<=x;i++)
scanf("%d",&a[i]);
for(i=x;i>=2;i--)
{
add(a[i],i);
add(i,a[i]);
}
dfs(1);
int maxdeep=0;
int pre=0;
is st;
st.pos=1;
st.step=0;
st.pre=0;
q.push(st);
flag[1]=1;
ll ans=0;
while(!q.empty())
{
is vv=q.front();
q.pop();
if(vv.pos!=1)
{
ans+=Dis_LCA(vv.pos,pre);
}
pre=vv.pos;
maxdeep=vv.step;
int pos=vv.pos;
for(i=head[vv.pos];i;i=e[i].next)
{
if(flag[e[i].to])
continue;
is en;
en.pos=e[i].to;
en.step=vv.step+1;
en.pre=vv.pos;
flag[e[i].to]=1;
q.push(en);
}
}
printf("%lld\n",ans);
}
return 0;
}


I

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long Ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-10;
const int  inf =0x7f7f7f7f;
const double pi=acos(-1);
const int maxn=40000;

struct node {
int x,y;
bool operator<(const node&a) const{
return this->x<a.x;
}
};
vector<node> A,B;
char s[10000];
int main()
{
int n;
while(~scanf("%d",&n))
{
A.clear();B.clear();
for(int i=1;i<=n;i++)
{
scanf("%s",s);
int l=0,r=0;
for(int j=0;s[j]!='\0';j++)
{
if(s[j]=='(') r++;
else if(!r) l++;
else r--;
}
if(l>r) B.push_back((node){r,l-r});
else  A.push_back((node){l,r-l});
}

sort(A.begin(),A.end());
sort(B.begin(),B.end());
int cntA=0,cntB=0;

bool flag=true;
for(int i=0;i<A.size();i++)
{
if(A[i].x>cntA) {flag=false;break;}
cntA+=A[i].y;
}

for(int i=0;i<B.size();i++)
{
if(B[i].x>cntB) {flag=false;break;}
cntB+=B[i].y;
}

if(cntA!=cntB) flag=false;
printf("%s\n",flag?"Yes":"No");
}
return 0;
}


K

题意:让你读完文章,并依次得到每个人的比赛次数。一共11个人,并且已经个了3个,你可以用这三个数检验你自己的答案。

傻逼题,细心阅读就可以了

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>

#define INF 0x3f3f3f3f
#define eps 1e-6

typedef long long LL;
const double pi = acos(-1.0);
const long long Mod = INF;
using namespace std;

int a[12] = {5,20,12,2,1,4,6,1,4,4,1,0};

int main()
{
int n;
cin >> n;
printf("%d\n",a
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: