我要举报本次校赛出题人的消极出题!!!

官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解)

A. 树链剖分数据结构板题

题目大意:我没看,看不懂。

基本思路:我不会。

参考代码:找Oyk老师和Czj老师去。

B. The background of water problem

题目大意(大写加粗的水题):给定$N$个学生和他们$K$个科目的成绩$S_i$,再给出各科目$K_i$的权重顺序$Q_i$,求排名之后,拥有id为$X$的是哪个学生。

基本思路:虽然$K$只有$10$,$S$只有$100$,但有M组查询,所以当然不能开个long long去hash每个学生。我们简单点,开个结构体,排个序,就好了。

参考代码

官方代码(将成绩和id分开放,避免在排序时复制构造大结构体):

  1. #include <cstdio>
  2. #include <string.h>
  3. #include <algorithm>
  4. #include <vector>
  5. using namespace std;
  6.  
  7. int N,K,M,X;
  8. int people[][];
  9. int cmpOrder[];
  10.  
  11. struct CmpNode{
  12. CmpNode(int x):id(x){}
  13. int id;
  14. bool operator < (const CmpNode &other) const
  15. {
  16. for(int i=; i<K; i++)
  17. {
  18. if(people[this->id][cmpOrder[i]] > people[other.id][cmpOrder[i]])
  19. return true;
  20. else if(people[this->id][cmpOrder[i]] < people[other.id][cmpOrder[i]])
  21. return false;
  22. }
  23. return this->id<other.id;
  24. }
  25. };
  26.  
  27. void solve(FILE *fin=stdin, FILE *fout=stdout)
  28. {
  29. int t;
  30. fscanf(fin,"%d",&t);
  31. while(t--)
  32. {
  33. fscanf(fin,"%d%d",&N,&K);
  34. vector<CmpNode> nodes;
  35. for(int i=;i<N;i++)
  36. {
  37. nodes.push_back(CmpNode(i));
  38. for(int j=;j<=K;j++)
  39. fscanf(fin,"%d",&people[i][j]);
  40. }
  41. fscanf(fin,"%d",&M);
  42. while(M--)
  43. {
  44. for(int i=;i<K;i++)
  45. fscanf(fin,"%d",cmpOrder+i);
  46. fscanf(fin,"%d", &X);
  47. sort(nodes.begin(),nodes.end());
  48. fprintf(fout,"%d\n",nodes[X-].id+);
  49. }
  50. }
  51. }
  52.  
  53. int main()
  54. {
  55. solve(stdin,stdout);
  56. return ;
  57. }

B. The background of water problem

非官方代码(这是通通放在结构体的例子,无论算法竞赛还是工程都不建议这么排序):

  1. #include <stdio.h>
  2. #include <algorithm>
  3.  
  4. int N, K, M, X;
  5. int order[];
  6.  
  7. struct stu {
  8. int id, score[];
  9. bool operator <(const stu&x) const {
  10. for(int i=; i<=K; i++)
  11. if(score[order[i]] != x.score[order[i]])
  12. return score[order[i]] > x.score[order[i]];
  13. return id < x.id;
  14. }
  15. }student[];
  16.  
  17. int main() {
  18. int T;
  19. scanf("%d", &T);
  20. while(T--) {
  21. scanf("%d%d", &N, &K);
  22. for(int i=; i<=N; i++) {
  23. student[i].id = i;
  24. for(int j=; j<=K; j++)
  25. scanf("%d", &student[i].score[j]);
  26. }
  27. scanf("%d", &M);
  28. while(M--) {
  29. for(int i=; i<=K; i++)
  30. scanf("%d", order+i);
  31. std::sort(student+, student++N);
  32. scanf("%d", &X);
  33. printf("%d\n", student[X].id);
  34. }
  35. }
  36. return ;
  37. }

B. The background of water problem

C. Oyk cut paper forever

题目大意

  永远的Oyk剪纸(大雾)。Oyk给面子Z大师,玩$C$轮剪纸,每轮给定一条长为$k$个单位的纸带,Z大师先手可以剪去(任意)$N_1$个单位,但不能不剪或全部拿走。此后每轮都只能剪$1$到$2\times N_1$个单位,能拿走最后一段纸带的人获胜,问Oyk第一次获胜是第几轮。

基本思路

  斐波那契博弈,证明参见:

  原题参见 hdoj 2516. 取石子游戏 等。

  首先知道了这是个斐波那契博弈,接下来我们要做的就是判断$K_i$是否为Fibonacci数。容易想到的是用递推打一个表,将Fibonacci数存起来或标记一下。但是我们知道斐波那契数列通项公式为$F_n=\frac1{\sqrt5}\left[\left(\frac{1+\sqrt5}2\right)^n-\left(\frac{1-\sqrt5}2\right)^n\right]$(比内公式),还知道判断一个数$x$是否为Fibonacci数只需判断$5x^2+4$或$5x^2-4$是否为完全平方数(参考:Wiki示例)(即判断开根号后是否为整数),于是Over。

参考代码

官方代码(丧sha病bi出题人改了好几波代码,我们还是假装下面的是对的吧):

  1. #include <cstdlib>
  2. #include <cstdio>
  3. #include <cmath>
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8. int T;
  9. scanf("%d",&T);
  10. while(T--){
  11. int n,i;
  12. int ans=;
  13. scanf("%d",&n);
  14. for(i = ;i<=n;i++){
  15. int a;
  16. scanf("%d",&a);
  17. if(!ans&&(sqrt(*a*a+)-(int)sqrt(*a*a+)<1e-||sqrt(*a*a-)-(int)sqrt(*a*a-)<1e-)){
  18. ans=i;
  19. }
  20. }
  21. if(ans)printf("%d\n",ans);
  22. else puts("Oyk forever!");
  23. }
  24. return ;
  25. }

C. OykOyk!

非官方代码(打表出奇迹):

  1. #include <stdio.h>
  2. using namespace std;
  3.  
  4. int flag[];
  5. void init() {
  6. int a = , b = ;
  7. while(b<=) {
  8. ++flag[b];
  9. b += a;
  10. a = b-a;
  11. }
  12. }
  13. int main() {
  14. int T; init();
  15. scanf("%d", &T);
  16. while(T--) {
  17. int C, k, res=;
  18. scanf("%d", &C);
  19. for(int i=; i<=C; i++) {
  20. scanf("%d", &k);
  21. if(!res&&flag[k])
  22. res = i;
  23. }
  24. res?printf("%d\n", res):puts("Oyk forever!");
  25. }
  26. return ;
  27. }

C. Oyk forever!

D. 最小费用流

题目大意

  挖$n$天的宝藏,每天需要$R_i$只铲子,当天用完会坏掉。有$3$种方式准备铲子:从商店买,$p$元一只;找铁匠$A$修理,每只$f$元同时修$m$天;找铁匠$B$修理,每只$s$元同时修$t$天。问最小花费。

基本思路

  最小费用流,参见网络流24题之餐巾问题。

参考代码

  1. #include <iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #define INF 99999999
  5. #define min(x,y) (x)>(y)?(y):(x)
  6. #define abs(x) ((x)>0?(x):-(x))
  7. #define E 50000
  8. struct p
  9. {
  10. int v,next,k,t,cost;
  11. }edge[];
  12. int n,m,ans,tot,S,T,head[],pre[],pid[],pop[];
  13. int mark[],dis[],now[];
  14. void addedge(int a,int b,int k,int cost)
  15. {
  16. edge[tot].v=b;
  17. edge[tot].k=k;
  18. edge[tot].cost=cost;
  19. edge[tot].t=tot+;
  20. edge[tot].next=head[a];
  21. head[a]=tot++;
  22.  
  23. edge[tot].v=a;
  24. edge[tot].k=;
  25. edge[tot].cost=-cost;
  26. edge[tot].t=tot-;
  27. edge[tot].next=head[b];
  28. head[b]=tot++;
  29. }
  30. int spfa()
  31. {
  32. int i,top,tail,cur;
  33. for(i=;i<=T;i++)
  34. dis[i]=INF,mark[i]=;
  35. top=tail=;
  36. pop[top++]=S;
  37. dis[S]=;
  38. mark[S]=;
  39. while(tail!=top)
  40. {
  41. cur=pop[tail++];
  42. tail%=;
  43. mark[cur]=;
  44. for(i=head[cur];i!=-;i=edge[i].next)
  45. if(edge[i].k>&&dis[edge[i].v]>dis[cur]+edge[i].cost)
  46. {
  47. dis[edge[i].v]=dis[cur]+edge[i].cost;
  48. pre[edge[i].v]=cur;
  49. pid[edge[i].v]=i;
  50. if(mark[edge[i].v]==)
  51. {
  52. mark[edge[i].v]=;
  53. pop[top++]=edge[i].v;
  54. top%=;
  55. }
  56. }
  57. }
  58. return dis[T];
  59. }
  60. int mincost()
  61. {
  62. int i,flow,tmp,ans,maxflow=;
  63. ans=;
  64. while()
  65. {
  66. tmp=spfa();
  67. if(tmp==INF) break;
  68. flow=INF;
  69. for(i=T;i!=S;i=pre[i])
  70. if(edge[pid[i]].k<flow)
  71. flow=edge[pid[i]].k;
  72. for(i=T;i!=S;i=pre[i])
  73. {
  74. edge[pid[i]].k-=flow;
  75. edge[edge[pid[i]].t].k+=flow;
  76. }
  77. maxflow+=flow;
  78. ans+=tmp*flow;
  79. }
  80. return ans;
  81. }
  82. int main()
  83. {
  84. freopen("in.txt","r",stdin);
  85. freopen("out.txt","w",stdout);
  86. int i,j,p,m1,f,m2,s,tmp;
  87. while(scanf("%d%d%d%d%d%d",&n,&p,&m1,&f,&m2,&s)!=EOF)
  88. {
  89. memset(edge,0xff,sizeof(edge));
  90. tot=n*+;
  91. S=;
  92. T=n*+;
  93. for(i=;i<=n;i++)
  94. {
  95. scanf("%d",&tmp);
  96. tmp++;
  97. addedge(S,i+n,INF,p);
  98. addedge(S,i,tmp,);
  99. addedge(i+n,T,tmp,);
  100. if(i<n) addedge(i,i+,INF,);
  101. if(i+m1<=n) addedge(i,n+i+m1,INF,f);
  102. if(i+m2<=n) addedge(i,n+i+m2,INF,s);
  103. }
  104. printf("%d\n",mincost());
  105. }
  106. return ;
  107. }

D. Dig the treasure

E. Wwj's work

题目大意:这题是HDOJ 4622. Reincarnation原题,有且仅有数据是自己造的。。

基本思路:求一个字符串的子串数目,标准的后缀自动机。当然似乎也可以后缀数组、后缀xxx什么的乱搞。

参考代码:(参考kuangbin的模板,和代码

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. const int CHAR = ;
  7. const int MAXN = ;
  8. struct SAM_Node {
  9. SAM_Node *fa, *next[CHAR];
  10. int len;
  11. int id,pos;
  12. SAM_Node() {}
  13. SAM_Node(int _len) {
  14. fa = ;
  15. len = _len;
  16. memset(next,,sizeof(next));
  17. }
  18. };
  19. SAM_Node SAM_node[MAXN*], *SAM_root, *SAM_last;
  20. int SAM_size;
  21. SAM_Node *newSAM_Node(int len) {
  22. SAM_node[SAM_size] = SAM_Node(len);
  23. SAM_node[SAM_size].id = SAM_size;
  24. return &SAM_node[SAM_size++];
  25. }
  26. SAM_Node *newSAM_Node(SAM_Node *p) {
  27. SAM_node[SAM_size] = *p;
  28. SAM_node[SAM_size].id = SAM_size;
  29. return &SAM_node[SAM_size++];
  30. }
  31. void SAM_init() {
  32. SAM_size = ;
  33. SAM_root = SAM_last = newSAM_Node();
  34. SAM_node[].pos = ;
  35. }
  36. void SAM_add(int x,int len) {
  37. SAM_Node *p = SAM_last, *np = newSAM_Node(p->len+);
  38. np->pos = len;
  39. SAM_last = np;
  40. for(; p && !p->next[x]; p = p->fa)
  41. p->next[x] = np;
  42. if(!p) {
  43. np->fa = SAM_root;
  44. return;
  45. }
  46. SAM_Node *q = p->next[x];
  47. if(q->len == p->len + ) {
  48. np->fa = q;
  49. return;
  50. }
  51. SAM_Node *nq = newSAM_Node(q);
  52. nq->len = p->len + ;
  53. q->fa = nq;
  54. np->fa = nq;
  55. for(; p && p->next[x] == q; p = p->fa)
  56. p->next[x] = nq;
  57. }
  58.  
  59. int sub[MAXN][MAXN];
  60. char S[MAXN];
  61. void read() {
  62. memset(sub, , sizeof(sub));
  63. scanf("%s", S);
  64. int len = strlen(S);
  65. for(int i=; i<len; i++) {
  66. SAM_init();
  67. for(int j=i; j<len; j++)
  68. SAM_add(S[j]-'a', j-i+);
  69. for(int j=; j<SAM_size; j++)
  70. sub[i][ SAM_node[j].pos+i- ]
  71. += SAM_node[j].len - SAM_node[j].fa->len;
  72. for(int j=i+; j<len; j++)
  73. sub[i][j] += sub[i][j-];
  74. }
  75. }
  76. void work() {
  77. int Q, l, r;
  78. scanf("%d", &Q);
  79. while(Q--) {
  80. scanf("%d%d", &l, &r);
  81. printf("%d\n", sub[l-][r-]);
  82. }
  83. }
  84. int main() {
  85. int T;
  86. scanf("%d", &T);
  87. while(T--) {
  88. read();
  89. work();
  90. }
  91. return ;
  92. }

E. Wwj's work

F. 防AK题,dfs+高斯消元

题目大意:我没看,看不懂。

基本思路:我不会。

参考代码:找Czj去。

G. Not Easy Math Problem

题目大意:$F(m,n)=\left\{\begin{matrix}\begin{aligned}&B*2^{m-1},&n=0\\&\sum_{i=1}^m F(i, n-1),&n>0\end{aligned}\end{matrix}\right.$,其中$m<10^6$,$n<10^3$,$B<10$,求$F(m,n)\%(1E8+7)$。

基本思路

  递推法

    先观察前面若干行若干列,发现各项系数构成杨辉三角。代几个数进去发现 $\displaystyle F(m,n)=B*\sum_{i=0}^{m-1}C_{m-i+n-2}^{n-1}*2^i$。

    $O(M)$肯定会TLE啊,算算算 $\displaystyle \frac{2F(m,n)-F(m,n)}{B}=C_{n-1}^{n-1}*2^m-C_{m+n-2}^{n-1}*2^0+\sum_{i=1}^{m-1}\left(C_{m-i+n-1}^{n-1}-C_{m-i+n-2}^{n-1}\right)*2^i$

    发现可以利用组合数性质,令$\displaystyle T(n-1)=\sum_{i=0}^{m-1}C_{m-i+n-2}^{n-1}*2^i$,$\displaystyle T(n-2)=\sum_{i=0}^{m-1}C_{m-i+n-2}^{n-2}*2^i$

    则$\displaystyle T(n-1)=C_{n-1}^{n-1}*2^m-C_{m+n-2}^{n-1}+T(n-2)-C_{m+n-2}^{n-2}$

    递推下去得$\displaystyle T(n-1)=2^{n-1}*2^m-2*\sum_{i=0}^{n-2}C_{m+n-2}^i-C_{m+n-2}^{n-1}$

    来个快速幂,再预处理下逆元和组合数,$O(log(M+N)+N)$跑得飞快($log$里面的$N$可以在前面预处理组合数的循环去掉,丑就是了)。

  数学归纳法

    参见 hdoj. 5490 题解。归纳公式为$\displaystyle F(m,n)=\frac{q*F(m,n-1)-B*C_{m+n-2}^{n-1}}{q-1}$,然后递推,时间复杂度$O(log(M)+N)$(如果用快速幂算$2^{m-1}$的话)。

参考代码(我的一定比标算好看):

  1. #include <stdio.h>
  2. const int MOD = ;
  3. inline int add(int a, int b) { return (a%MOD+b%MOD)%MOD; }
  4. inline int sub(int a, int b) { return ((a-b)%MOD+MOD)%MOD; }
  5. inline int mul(int a, int b) { return int((long long)a%MOD*(b%MOD)%MOD); }
  6. inline int pow(int x, int n) {
  7. int res = ;
  8. while(n) {
  9. if(n&) res = mul(res, x);
  10. x = mul(x, x);
  11. n >>= ;
  12. }
  13. return res;
  14. }
  15. int inv[]={,};
  16. void init() {
  17. for(int i=; i<=; i++)
  18. inv[i] = mul(inv[MOD%i], MOD-MOD/i);
  19. }
  20. int B, M, N;
  21. void read() {
  22. scanf("%d%d%d", &B, &M, &N);
  23. }
  24. int Binomial[]={};
  25. void work() {
  26. for(int i=; i<N; i++)
  27. Binomial[i] = mul(mul(Binomial[i-], M+N-i-), inv[i]);
  28. int res = pow(, M+N-);
  29. for(int i=; i<N; i++)
  30. res = sub(res, mul(Binomial[i], ));
  31. res = mul(add(res, Binomial[N-]), B);
  32. printf("%d\n", res);
  33. }
  34. int main() {
  35. int T; init();
  36. scanf("%d", &T);
  37. while(T--) {
  38. read();
  39. work();
  40. }
  41. return ;
  42. }

比标算好看一丢丢的 G.

H. Party!

题目大意

  Wwj和他的女朋友们总共$N$个人去开趴体。每个人如果还没把自己的礼物送出去的话,就可以从别人手中收到礼物。第$i$个人得到第$j$人礼物的同时,也会得到一个快乐指数$H_{i,\ j}$。求所有人的快乐指数的总和的最大值。

基本思路

  诶?有人用贪心做?有人用搜索做?听说还有人用最小生成树做?诶等等那个用无向图MST的什么心态?这不是有向图?(我的天呐.jpg)

  这题可以跑一个网络流,当然也可以DP。谁告诉你给一个矩阵就一定是图论题了?mdzz。

  能DP我当然不写网络流,考虑收礼物状态矩阵$M$,$M_{i,\ j}$代表第$i$个人收没收第$j$人的礼物($i\neq j$),收了为$1$,没收为$0$。由于每个人只有一份礼物,他只能送给一个人,所以在同一列内最多只有$1$个$1$,所以状态矩阵$M$可以直接拍扁。好的,$N\leq 10$,我们可以愉快地状态压缩了,状态数$2^N-1$,dp时间复杂度$O(2^N N^2)$。

  考虑任意状态state,如果第$i\geq 0$位为$1$(即$state\&(1<<i)!=0$),则表明该状态下第$i$个人已经把他的礼物给出去了(当然也不可能发生给自己的情况)。对每一个状态求最大快乐指数,再取所有状态的最大值。

参考代码

  1. #include <stdio.h>
  2.  
  3. int N, H[][];
  4. inline void getMax(int&n, int x) { if(n<x) n=x; }
  5. void read() {
  6. scanf("%d", &N);
  7. for(int i=; i<N; i++)
  8. for(int j=; j<N; j++)
  9. scanf("%d", H[i]+j);
  10. }
  11. void work() {
  12. int maxState = <<N, dp[maxState]={};
  13. for(int state=; state<maxState; state++)
  14. for(int i=; i<N; i++) if(!(state&(<<i)))
  15. for(int j=; j<N; j++) if(i!=j&&!(state&(<<j)))
  16. getMax(dp[state+(<<j)], dp[state]+H[i][j]);
  17. int res = ;
  18. for(int state=; state<maxState; state++)
  19. getMax(res, dp[state]);
  20. printf("%d\n", res);
  21. }
  22. int main() {
  23. int T;
  24. scanf("%d",&T);
  25. while(T--) {
  26. read();
  27. work();
  28. }
  29. return ;
  30. }

H. Party!

I. Square

题目大意:$N\times N$的矩阵,每个格子要填$0$或$1$,要求每行每列中$1$的个数要是奇数个。

基本思路:不考虑限制条件,有$2^{N^2}$种方案对吧?能乱填对吧?那如何保证每行每列中$1$的个数是奇数个?在旁边加多一行加多一列(即$(N+1)\times(N+1)$),对于每一行每一列,如果$1$的个数是偶数个,再填个$1$,否则填$0$进去。啥?剩下那个格子怎么办?会一边奇数一边偶数?嗯,由于是$N\times N$,所以是不可能的。因此$S_N=2^{(N-1)^2}$,快速幂或者奇怪的优化即可。

参考代码

官方代码(分块处理,把47改成15,不用long long用int也是可以的,当然时间就差个2.5倍咯):

  1. #include <stdio.h>
  2. #define ULL unsigned long long
  3. int main() {
  4. ULL res;
  5. int n;
  6. int T;
  7. scanf("%d",&T);
  8. while(T--) {
  9. scanf("%d",&n);
  10. res=;
  11. for(ULL i = ; i<(ULL)(n-)*(n-)/; i++)
  12. res=(res<<)%;
  13. for(ULL i = ; i<(ULL)(n-)*(n-)%; i++)
  14. res=(res*)%;
  15. printf("%d\n",res);
  16. }
  17. return ;
  18. }

I. Square

非官方代码(快速幂,怎么说也是log的复杂度,比上面奇怪的优化要快就是了):

  1. #include <stdio.h>
  2. const int MOD = ;
  3. long long pow(long long x, int n) {
  4. long long res = 1LL;
  5. while(n) {
  6. if(n&) res = res*x%MOD;
  7. x = x*x%MOD;
  8. n >>= ;
  9. }
  10. return res;
  11. }
  12. int main() {
  13. int T, N;
  14. scanf("%d",&T);
  15. while(T--) {
  16. scanf("%d",&N);
  17. --N; N *= N;
  18. printf("%d\n", pow(, N));
  19. }
  20. return ;
  21. }

I. Square

J. Rotate and skew

题目大意

  windows系统里面有个“画图”工具,相信大家一定不会陌生。但里面没有旋转任意$x$角度的功能,只有“扭曲”的功能。如逆时针旋转$28^\circ$,我们发现可以先对$x$轴扭曲$-14^\circ$,再对$y$轴扭曲$25^\circ$,再对$x$轴扭曲$-14^\circ$,就成功辣!问给定角度$x$,输出三次扭曲的角度。

基本思路

  好多同学可能一开始先取个基向量,比如$\vec b=(0,1)$,然后想$x$轴扭曲$-14^\circ$应该是$\vec{b'}=(tan14^\circ,1)$,$y$轴再扭曲$25^\circ$应该是$\vec{b''}=(tan14^\circ, 1-tan25^\circ)$,再扭曲一下……再$arc tan$一下……咦?怎么出来的不是$28^\circ$了?

  Naive。如果是这样那还叫扭曲吗?那叫拉伸!你倒是把$x$乘进去啊!把$y$乘进去啊!

  • 首先考虑基向量$\vec a=(1,0)$。设旋转角度$\theta$。先水平扭曲任意角度,不变。垂直扭曲$\varphi$,$\vec{a'}=(1, tan\varphi)$,再水平扭曲一次得$\vec{a''}=(1-tan(x), tan\varphi)$,和$tan\theta$解一下发现$x=\frac\theta2$,于是知道了水平扭曲角度。
  • 正解(1):考虑向量$\vec x=\begin{bmatrix}x\\y\end{bmatrix}$,水平扭曲矩阵$A=\begin{bmatrix}1&tan(-\frac\theta2)\\0&1\end{bmatrix}$, ($A\vec x=\begin{bmatrix}x+ytan(-\frac\theta2)\\y\end{bmatrix}$,看不懂的学线代去)
    • 三个扭曲矩阵相乘应该是$M=ABA$,其中我们要求的是中间的垂直扭曲矩阵$B$。
    • 已知旋转矩阵$M=\begin{bmatrix}cos\theta&-sin\theta\\sin\theta&cos\theta\end{bmatrix}$,解得$B=\begin{bmatrix}1&0\\sin\theta&1\end{bmatrix}$。
    • 但是我们的垂直扭曲矩阵应该要长成$B=\begin{bmatrix}1&0\\tan\varphi&1\end{bmatrix}$的样子。
    • 所以我们需要用$tan$正切值去模拟$sin$正弦值(本来就是要求用扭曲模拟旋转)。
  • 正解(2):再考虑基向量$\vec b=(0,1)$。
    • 联立化简 $\left\{\begin{matrix}\begin{aligned}&x_1=x_0+y_0*tan(-\frac\theta2)\\&y_1=y_0+x_1*tan(\varphi)\\&x_2=x_1+y_1*tan(-\frac\theta2)\end{aligned}\end{matrix}\right.$,$\left\{\begin{matrix}\begin{aligned}&x_0=0,\ y_0=1\\&tan(-\theta)=\frac{x_2}{y_1}\end{aligned}\end{matrix}\right.$  得  $\displaystyle\frac{tan(\frac\theta2)[sec(\theta)tan(\varphi)-tan(\theta)]}{tan(\frac\theta2)tan(\varphi)-1}=0$
    • 解 $sec(\theta)tan(\varphi)=tan(\theta)$ 得垂直扭曲角度 $\varphi=tan^{-1}sin(\theta)$
    • 啥?你还要$+k\pi$?你还要分母不为$0$?$\theta$不为$0$?这都要我解,你咋不上天呢。
  • 发现题目对精度要求不高,反正切取个整即可。也可以直接打个垂直扭曲角度的表。
  • 更多请参考  Matrix67—线性代数的妙用:怎样在Windows画图软件中实现28度旋转?

参考代码

对基向量$\vec b=(0,1)$的模拟:

  1. #include <stdio.h>
  2. #include <math.h>
  3. const double PI = acos(-.L);
  4. int main() {
  5. double x = 0.0, y = 1.0;
  6. x = x + tan(-.*PI/.) * y;
  7. y = y + tan(.*PI/.) * x;///注意这里是tan25模拟sin28,若这里直接用sin28则最后atan回来的结果是28.0整
  8. x = x + tan(-.*PI/.) * y;
  9. printf("%f\n", atan(x/y)*./PI);
  10. return ;
  11. }

官方代码:

  1. // http://scarky.com/widget/getiframe/PLNRB5QG/
  2. #include <stdio.h>
  3. int y[]={,,,,,,,,,,,,,,,,,,,,,,};
  4. int main(int i) {
  5. while(~scanf("%d", &i))
  6. i/=, printf("%d %d %d\n", -i, i>?y[i]:-y[-i], -i);
  7. return ;
  8. }

非官方代码:

  1. #include <stdio.h>
  2. #include <math.h>
  3. const double PI = acos(-.L);
  4. int main() {
  5. int x;
  6. while(~scanf("%d", &x))
  7. printf("%d %.f %d\n", -x/, round(atan(sin(x*PI/.))*./PI), -x/);
  8. return ;
  9. }

——原创by BlackStorm,转载请注明出处。

本文地址:http://www.cnblogs.com/BlackStorm/p/5380872.html

2016 华南师大ACM校赛 SCNUCPC 非官方题解的更多相关文章

  1. 福建工程学院第十四届ACM校赛M题题解 fwt进阶,手推三进制fwt

    第九集,结束亦是开始 题意: 大致意思就是给你n个3进制的数字,让你计算有多少对数字的哈夫曼距离等于i(0<=i<=2^m) 思路: 这个是一个防ak题,做法是要手推公式的fwt 大概就这 ...

  2. 福建工程学院第十四届ACM校赛J题题解

    第六集,想不到你这个浓眉大眼的都叛变革命了 题意: 给你两个只包含01的字符串S和T,问你在允许一次错误的情况下,T是否能成为S的子串 思路: 这个问题的解法挺多,我是用fft匹配的,也比较简单,针对 ...

  3. 福建工程学院第十四届ACM校赛G题题解

    外传:编剧说了不玩游戏不行 题意: 有n个石堆,我每次只能从某一堆中取偶数个石子,你取奇数个,我先手,先不能操作的人输.问最后谁能赢. 思路: 这个题仔细想想,就发现,取奇数的人有巨大的优势,因为假设 ...

  4. 福建工程学院第十四届ACM校赛B题题解

    第二集,未来的我发量这么捉急的吗 题意: 有n个数,请问有多少对数字(i,j)(1<=i<j<=n),满足(a[i]^a[j])+((a[i]&a[j])<<1) ...

  5. 2014哈商大ICPC/ACM校赛解题报告

    被debug邀请去參加校赛,哎,被虐..我对不起工大.. 由于本人不搞ACM,算法处于HelloWorld水准.. 虽然题目除了鸟不拉屎星人之外都非常水,但我能做到这个程度,全然是超水平发挥了.. 数 ...

  6. 2019 西电ACM校赛网络赛 题解

    今年题目难度有较大提升,总体与往年类似,数学题居多.以下为我通过的部分题解. 赛题链接:http://acm.xidian.edu.cn/contest.php?cid=1053 A - 上帝视角 我 ...

  7. 2017南开ACM校赛(网络赛) 民间题解

    orz 首先说一下这个只是民间题解,可能会有很多错误 程序还没有评测,所以可能存在问题 C题比赛的时候没想到..后来发现是个模板题,所以没有代码 希望这份题解能对读者有所启发吧... A题 直接倒序枚 ...

  8. [BNUZOJ1261][ACM][2016北理校赛]方块消除(栈,字符串)

    玩过方块消除游戏吗?现在规定当有两个或两个以上相邻且颜色相同的方块在一起的时候,它们就会产生消除反应.当存在多个消除反应同时产生时,最下的反应先执行.现在只给你其中一列,求最后剩下的方块结果. 输入要 ...

  9. (2015年郑州轻工业学院ACM校赛题)H 五子棋

    我们最后选题策略失败,选到五子棋这题,没想到这题非常麻烦,最后也没做出来! 比赛结束后发了题解再做才做出来! 不得不说 这题真的很麻烦 一个需要比较细致分类讨论的题目.判定棋盘是否合法应考虑如下几种情 ...

随机推荐

  1. [SQL] SQL 基础知识梳理(四) - 数据更新

    SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...

  2. ASP.NET 5 WebApi 返回 HttpResponseMessage

    首先,ASP.NET 5 没有了 MVC 和 WebApi 的区分,都属于 ASP.NET 5,从 Controller 的继承就可以看出,原来 ASP.NET WebApi 2 ValuesCont ...

  3. AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilityManager

    做ios开发,AFNetworking 这个网络框架肯定都非常熟悉,也许我们平时只使用了它的部分功能,而且我们对它的实现原理并不是很清楚,就好像总是有一团迷雾在眼前一样. 接下来我们就非常详细的来读一 ...

  4. c#编程基础之ref、out参数

    引例: 先看这个源码,函数传递后由于传递的是副本所以真正的值并没有改变. 源码如下: using System; using System.Collections.Generic; using Sys ...

  5. Apworks框架实战(五):EasyMemo的领域模型设计

    在上一讲中,我们已经新建了一个聚合根对象Account,并已经可以开始设计领域模型了.在这一讲中,我们会着重介绍EasyMemo领域模型的分析和设计,并引入Visual Studio Ultimate ...

  6. 说一说javascript跨域和jsonp

    同源策略 在浏览器的安全策略中“同源策略”非常如雷贯耳,说的是协议.域名.端口相同则视为同源,域名也可换成IP地址,不同源的页面脚本不能获取对方的数据. 要是想使用XMLHttpRequest或者常规 ...

  7. 你所不知道的linq

    问题的提出 昨天在qq群问了一个linq的问题被人鄙视了.题目大概类似于 var reuslt=from s in new List<string>() select s; 问from.. ...

  8. 在基于MVC的Web项目中使用Web API和直接连接两种方式混合式接入

    在我之前介绍的混合式开发框架中,其界面是基于Winform的实现方式,后台使用Web API.WCF服务以及直接连接数据库的几种方式混合式接入,在Web项目中我们也可以采用这种方式实现混合式的接入方式 ...

  9. js正则表达式校验非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. java类初始化顺序

    一.概述 了解类的初始化顺序,可以更灵活.方便的构造一个类. 二.类初始化顺序 2.1 示例 public class InitialOrderTest { public static void ma ...