0924解题报告
2016-09-25 14:14
211 查看
T1
题目描述
你有 nm 颗糖果。如果有 n 个小朋友来你家,你需要分给他们每人 m 颗糖;如果来的是m 个小朋友,你就要分给每人 n 颗。你打算把糖果分装在 k 个盒子里,每个盒子分别放几颗糖由你来决定。分糖果时,盒子是不能被拆开的。(小朋友们拿到的只能是装着糖果的盒子,而不是散装的糖果)你希望最小化盒子的数量 k,使得不论来了 n 个还是 m 个小朋友,你都能按照要求给他们分糖果。
一个很魔性的题,不知道怎么就A了。。。(只是在gcd中加了点东西)
T2
题目描述
Byteotia 由 n 座城市组成。城市之间连有 m 条道路,道路可以双向通行。其中第 i 条道路连接 ui; vi 两座城市,通过这条道路需要花费 ti 个小时。城市和道路都从 1 开始编号。Byteotia 的计时方法比较奇特,一天共有 K 个小时。我们假定一天的起始时刻是 0 点整。Byteasar 打算在某天的 0 点整从城市 x 出发,前往城市 y。旅途中只能沿着道路行走,而不允许原地休息。Byteasar 不在乎自己的旅行花费了多少天,他只希望到达 y 的时刻在一天中尽可能早,即如果在某天的 T 点整 (0 T < K) 到达城市 y,他希望使得 T 尽可能小。为了达到这一目标,Byteasar 的旅行路径中允许多次经过同一条道路,也允许多次经过同一个城市(包括 x; y)。如果多次经过 y,最后一次到达 y 的时刻才算作到达时刻。Byteasar 可能有多组旅行计划,他想寻求你的帮助。Byteotia 的计时方法也常常改变,所以你需要对每一组 xj ; yj ;Kj 求出最小的 T。
问题实质是求出 x 到 y 的路径,路径长度模 K 后最小。
于是随便用二分图搞一搞,然而wa了几组,不知道为什么。
T3
最近 JC 同学刚学会 gcd,于是迷上了与 gcd 有关的问题。今天他又出了一道这样的题目,
想要考考你,你能顺利完成吗?
给定一个长度为 n 的字符串 s[1::n],串仅包含小写字母。对于区间 [l; r],你需要回答 s[l::r]
中有多少个长度为 3 的子序列组成了"gcd",即有多少组 (i; j; k) 满足 l i < j < k r; s[i] =
'g'; s[j] = 'c'; s[k] = 'd'。
一个奇怪的前缀和维护。(各种前缀和,各种恶心)
考试前被Cydiater坑了一把,没有在现场参加考试,只能在家颓废,最后只交了一道题,还好,长者保佑,A掉了。
然而写题时,T2和T3都没有想出正解,由此可见我还是很弱,与此同时Cydiater现场A掉2题。
题目描述
你有 nm 颗糖果。如果有 n 个小朋友来你家,你需要分给他们每人 m 颗糖;如果来的是m 个小朋友,你就要分给每人 n 颗。你打算把糖果分装在 k 个盒子里,每个盒子分别放几颗糖由你来决定。分糖果时,盒子是不能被拆开的。(小朋友们拿到的只能是装着糖果的盒子,而不是散装的糖果)你希望最小化盒子的数量 k,使得不论来了 n 个还是 m 个小朋友,你都能按照要求给他们分糖果。
一个很魔性的题,不知道怎么就A了。。。(只是在gcd中加了点东西)
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<ctime> #include<cmath> #include<algorithm> using namespace std; int n,m,t,ans; void gcd(int a,int b) { if(b==0) return; gcd(b,a%b); ans+=b*(a/b); } void Gcd(int a,int b) { if(b==0) return; for(int i=1;i<=a/b*b;i++) printf("%d ",b); Gcd(b,a%b); } inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } int main() { freopen("candy.in","r",stdin); freopen("candy.out","w",stdout); n=read(); m=read(); t=read(); if(t==0) { if(n<m) swap(n,m); gcd(n,m); printf("%d\n",ans); } else { if(n<m) swap(n,m); gcd(n,m); printf("%d\n",ans); Gcd(n,m); printf("\n"); } return 0; }
T2
题目描述
Byteotia 由 n 座城市组成。城市之间连有 m 条道路,道路可以双向通行。其中第 i 条道路连接 ui; vi 两座城市,通过这条道路需要花费 ti 个小时。城市和道路都从 1 开始编号。Byteotia 的计时方法比较奇特,一天共有 K 个小时。我们假定一天的起始时刻是 0 点整。Byteasar 打算在某天的 0 点整从城市 x 出发,前往城市 y。旅途中只能沿着道路行走,而不允许原地休息。Byteasar 不在乎自己的旅行花费了多少天,他只希望到达 y 的时刻在一天中尽可能早,即如果在某天的 T 点整 (0 T < K) 到达城市 y,他希望使得 T 尽可能小。为了达到这一目标,Byteasar 的旅行路径中允许多次经过同一条道路,也允许多次经过同一个城市(包括 x; y)。如果多次经过 y,最后一次到达 y 的时刻才算作到达时刻。Byteasar 可能有多组旅行计划,他想寻求你的帮助。Byteotia 的计时方法也常常改变,所以你需要对每一组 xj ; yj ;Kj 求出最小的 T。
问题实质是求出 x 到 y 的路径,路径长度模 K 后最小。
于是随便用二分图搞一搞,然而wa了几组,不知道为什么。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> using namespace std; #define MAXN 50010 struct node{int y,next,v;}e[MAXN*2]; int n,m,k,len,flag,f[MAXN],Link[MAXN],g[MAXN],c[MAXN],check[MAXN]; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } int find(int x) {return f[x]==x?x:f[x]=find(f[x]);} int gcd(int a,int b) {return b==0?a:gcd(b,a%b);} void insert(int x,int y,int v) {e[++len].next=Link[x]; Link[x]=len; e[len].y=y; e[len].v=v;} bool color(int x,int cl) { c[x]=cl; for(int i=Link[x];i;i=e[i].next) { if(!c[e[i].y]) { if(!color(e[i].y,3-cl)) return 0; } else if(c[e[i].y]==cl) return 0; } return 1; } int main() { freopen("pod.in","r",stdin); freopen("pod.out","w",stdout); n=read(); m=read(); k=read(); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++) { int x=read(),y=read(),v=read(); if(rand()%2) swap(x,y); insert(x,y,v); insert(y,x,v); x=find(x); y=find(y); f[x]=y; g[y]=gcd(gcd(g[y],g[x]),v); } for(int i=1;i<=n;i++) if(!c[i]) if(!color(i,1)) check[find(i)]=1; for(int i=1;i<=k;i++) { int x=read(),y=read(),mo=read(); int d=gcd(g[find(y)],mo); if(find(x)!=find(y)) printf("NIE\n"); else if((mo/d)&1)printf("0\n"); else if(check[find(x)]) printf("0\n"); else if(c[x]==c[y]) printf("0\n"); else printf("%d\n",d); } return 0; }
T3
最近 JC 同学刚学会 gcd,于是迷上了与 gcd 有关的问题。今天他又出了一道这样的题目,
想要考考你,你能顺利完成吗?
给定一个长度为 n 的字符串 s[1::n],串仅包含小写字母。对于区间 [l; r],你需要回答 s[l::r]
中有多少个长度为 3 的子序列组成了"gcd",即有多少组 (i; j; k) 满足 l i < j < k r; s[i] =
'g'; s[j] = 'c'; s[k] = 'd'。
一个奇怪的前缀和维护。(各种前缀和,各种恶心)
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<ctime> #include<algorithm> using namespace std; int n,sl[80010],sr[80010],ssl[80010],ssr[80010],slr[80010],su[80010]; char ch[80010]; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } int main() { freopen("gcd.in","r",stdin); freopen("gcd.out","w",stdout); scanf("%s",ch+1); n=strlen(ch+1); for(int i=1;i<=n;i++) sl[i]=sl[i-1]+(ch[i]=='g'); for(int i=n;i;i--) sr[i]=sr[i+1]+(ch[i]=='d'); for(int i=1;i<=n;i++) { slr[i]=slr[i-1]+(ch[i]=='c')*sl[i]*sr[i]; ssl[i]=ssl[i-1]+(ch[i]=='c')*sl[i]; ssr[i]=ssr[i-1]+(ch[i]=='c')*sr[i]; su[i]=su[i-1]+(ch[i]=='c'); } int q=read(); while(q--) { int x=read(),y=read(); int ans=slr[y]-slr[x-1]-(ssr[y]-ssr[x-1])*sl[x-1]-(ssl[y]-ssl[x-1])*sr[y+1]+(su[y]-su[x-1])*sl[x-1]*sr[y+1]; ans&=(~(1<<31)); printf("%d\n",ans); } return 0; }
考试前被Cydiater坑了一把,没有在现场参加考试,只能在家颓废,最后只交了一道题,还好,长者保佑,A掉了。
然而写题时,T2和T3都没有想出正解,由此可见我还是很弱,与此同时Cydiater现场A掉2题。
相关文章推荐
- 【LeetCode】Minimum Path Sum 解题报告
- POJ 1003解题报告
- [Leetcode] 545. Boundary of Binary Tree 解题报告
- POJ 3352 Road Construction解题报告
- 百练 2820 古代密码 解题报告
- Codeforces Round #274 (Div. 2) 解题报告 (C D E)
- poj1004 解题报告
- pku acm 2021题解题报告
- poj1753 Flip Game 解题报告
- LeetCode: Populating Next Right Pointers in Each Node II 解题报告
- poj 2152解题报告
- [Updating] Codeforces Round #411 解题报告
- Leetcode Remove Duplicates from Sorted Array 解题报告
- NOIP2012提高组解题报告
- codeforces Round #261(div2) C解题报告
- POJ 1154 解题报告
- leetcode解题报告(22):Two Sum II - Input array is sorted
- LeetCode: Set Matrix Zeroes 解题报告
- C2第三次作业解题报告
- poj1328解题报告.