【hihoCoder】【挑战赛#12】
模拟+枚举+模拟……+构造
QAQAQQQ rank12求杯子!
A 顺子
……模拟题,分类讨论一下就好了……比如当前四张牌是不是同一花色……是不是连续的四张牌,如果是连续的四张牌,是不是两边的……(呀我好像忘了判左边。。。只判了J Q K A。。。。没判A 2 3 4。。。
没关系加几个字符就好了……嗯代码已改
1 //hihocoder 12 A 2 #include<vector> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 using namespace std; 12 typedef long long LL; 13 inline int getint(){ 14 int r=1,v=0; char ch=getchar(); 15 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 16 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 17 return r*v; 18 } 19 const int N=1e5+10; 20 /*******************template********************/ 21 22 bool hv[20]; 23 char s[7][5]; 24 int id1(char ch){ 25 if (ch>='2' && ch<='9') return ch-'0'; 26 if (ch=='A') return 1; 27 if (ch=='J') return 11; 28 if (ch=='Q') return 12; 29 if (ch=='K') return 13; 30 } 31 int id2(char ch){ 32 if (ch=='S') return 1; 33 if (ch=='H') return 2; 34 if (ch=='C') return 3; 35 if (ch=='D') return 4; 36 } 37 int main(){ 38 bool sign=0; 39 F(i,1,4){ 40 scanf("%s",s[i]); 41 if (s[i][0]=='1'){hv[10]=1; s[i][1]=s[i][2];continue;} 42 hv[id1(s[i][0])]=1; 43 if (id1(s[i][0])==1) hv[14]=1; 44 } 45 F(i,2,4) if (s[i][1]!=s[i-1][1]) sign=1; 46 F(i,1,11){ 47 int sum=0; 48 F(j,0,3) sum+=hv[i+j]; 49 if (sum==4){ 50 if (i!=11 &&i!=1){ 51 if (sign) puts("1/6"); 52 else puts("1/8"); 53 }else{ 54 if (sign) puts("1/12"); 55 else puts("1/16"); 56 } 57 return 0; 58 } 59 } 60 F(j,11,14) 61 F(i,1,10){ 62 int sum=0; 63 F(j,0,4) sum+=hv[i+j]; 64 if (sum==4){ 65 if (sign) puts("1/12"); 66 else puts("1/16"); 67 return 0; 68 } 69 } 70 puts("0/1"); 71 return 0; 72 }
B 计数
介个……O(n)枚举吧,$10^7$的枚举还是不虚的。
然而这题我又傻逼了……我用的是set插入的,带了log……居然还能过(可能是满足条件的点太少?其实是数据太弱。。。?
1 //hihocoder 12 B 2 #include<set> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define rep(i,n) for(int i=0;i<n;++i) 10 #define F(i,j,n) for(int i=j;i<=n;++i) 11 #define D(i,j,n) for(int i=j;i>=n;--i) 12 using namespace std; 13 typedef long long LL; 14 inline int getint(){ 15 int r=1,v=0; char ch=getchar(); 16 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 17 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 18 return r*v; 19 } 20 const int N=1e5+10; 21 /*******************template********************/ 22 23 LL n,L,R; 24 set<LL>s; 25 26 int main(){ 27 n=getint(); L=getint(); R=getint(); 28 F(i,1,10000000){ 29 LL t=i^(n*i); 30 if (t>=L && t<=R) s.insert(t); 31 } 32 printf("%d\n",s.size()); 33 return 0; 34 }
C 永恒游戏
神题,蒟蒻并不会做……经过大胆猜想,不用(hui)证明,yy了一个做法:每次找度数最小的可操作点进行操作,然后模拟10W次……居然就过了……过了……了……
题解说:
有一个定理保证,对于一个固定的初始局面,不论怎么操作,要么可以无限操作下去,要么在相同步数之后停在相同的局面上。所以只需要模拟100000次即可知道本题答案。
定理的证明可以在以下论文中找到 http://www.cs.elte.hu/~lovasz/morepapers/chips.pdf (定理1.1)
E文的paper差评QAQ,蒟蒻太傻逼看不懂啊QAQ
1 //hihocoder 12 C 2 #include<vector> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 using namespace std; 12 typedef long long LL; 13 inline int getint(){ 14 int r=1,v=0; char ch=getchar(); 15 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 16 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 17 return r*v; 18 } 19 const int N=210; 20 /*******************template********************/ 21 22 23 int n,m,a[N][N],du[N],num[N]; 24 int main(){ 25 n=getint(); m=getint(); 26 F(i,1,n) num[i]=getint(); 27 F(i,1,m){ 28 int x=getint()+1,y=getint()+1; 29 a[x][y]=a[y][x]=1; 30 du[x]++; du[y]++; 31 } 32 F(i,1,100001){ 33 int mn=10000,t=-1; 34 F(j,1,n) 35 if (num[j]>=du[j]) 36 if (du[j]<mn) mn=du[j],t=j; 37 if (t==-1){ 38 printf("%d\n",i-1); return 0; 39 } 40 F(j,1,n){ 41 if (a[t][j]) num[j]++,num[t]--; 42 } 43 } 44 puts("INF"); 45 return 0; 46 }
D 天下无骰
神一样的构造题……
然而我连题都没读对
其实是:决策树上的叶子可以有很多,而且可以多个叶子标相同的号,只要保证标同一个号的叶子的概率之和为$\frac{1}{n}$即可……
然而如果是必须要只能一个叶子呢?我yy的做法是这样的:(口胡时间√)
首先我们一定要有一个$\frac{1}{2}$的硬币……因为最后两个叶子之间的概率必然得相等……
然后我们现在就可以处理n是2的幂的情况了
然后我们考虑另一个硬币可以做什么?可以将不是2的幂的情况,比如5,变成2的幂的和(1+4)然而只能分出来两个……所以是二进制表示中1的数量=2的才可以……
然而这并不是本题正解233只是感觉这个思路很有趣不想让它就这么消失……说不定哪天我可以出一道题(大雾)?2333。。。。
至于正解。。。太麻烦了蒟蒻看不懂QAQ
1 //hihocoder 12 D 2 #include<vector> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 using namespace std; 12 typedef long long LL; 13 inline int getint(){ 14 int r=1,v=0; char ch=getchar(); 15 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 16 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 17 return r*v; 18 } 19 const int N=5e5+10; 20 /*******************template********************/ 21 22 int n,m,v[N],c[N][2],tot,a[N],num,p0,q0,p1,q1; 23 bool sign[N]; 24 25 void dfs(int x,int a){ 26 if (a==1){ 27 sign[x]=1; 28 return; 29 } 30 if (a%q0==0){ 31 v[x]=0; 32 c[x][0]=++tot; 33 c[x][1]=++tot; 34 dfs(c[x][0],a/q0*p0); 35 dfs(c[x][1],a/q0*(q0-p0)); 36 return; 37 } 38 if (a%q1==0){ 39 v[x]=1; 40 c[x][0]=++tot; 41 c[x][1]=++tot; 42 dfs(c[x][0],a/q1*p1); 43 dfs(c[x][1],a/q1*(q1-p1)); 44 return; 45 } 46 } 47 void work(){ 48 puts("YES"); 49 printf("%d %d %d %d\n",p0,q0,p1,q1); 50 dfs(0,n); 51 int num=0; 52 printf("%d\n",tot+1); 53 F(i,0,tot-1){ 54 if (sign[i]){ printf("E %d\n",num++); continue;} 55 printf("C %d %d %d\n",v[i],c[i][0],c[i][1]); 56 } 57 printf("E %d",num++); 58 } 59 60 int cnt(int x){ 61 int ans=0; 62 while(x){ 63 ans+=x&1; 64 x>>=1; 65 } 66 return ans; 67 } 68 int main(){ 69 m=n=getint(); 70 F(i,3,n){ 71 if (cnt(i)<=2) a[++num]=i; 72 } 73 while((m&1)==0) m>>=1; 74 while(m%3==0) m/=3; 75 p1=1,q1=2; 76 if (m==1){ 77 p0=1,q0=3; 78 work(); 79 return 0; 80 } 81 F(i,1,num){ 82 m=n; 83 while((m&1)==0) m>>=1; 84 while(m%a[i]==0) m/=a[i]; 85 if (m==1){ 86 q0=a[i]; 87 p0=a[i]&(-a[i]); 88 work(); 89 return 0; 90 } 91 } 92 puts("NO"); 93 return 0; 94 }