1、大搬家
分析:
一个不是很水的递推,只要想明白了怎么能实现三次搬家能回来,题就变水了;
只有a->b,之后两个都不动,再b->a,便可以实现三次搬家搬回原样,那么这个题便转化为配对的种数了
设S[n]为n时的情况种数,有两种情况:
(1)、n不动,有S[n-1]种情况
(2)、n和前面(n-1)中的任意一个配对,有(n-1)*S[n-2]
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> typedef long long LL; using namespace std; const int N = 1000000007; LL s[1000005]; void init(){ s[0] = s[1] = 1; for(int i = 2; i <= 1000000; i++) s[i] = (s[i - 1] + (i - 1) * s[i - 2]) % N; } int main() { init(); int T, n; scanf("%d", &T); for(int i = 1; i <= T; i++) { scanf("%d", &n); printf("Case #%d:\n%d\n", i, s[n]); } return 0; }
2、放盘子
分析:只有放不进一个盘子时,才会输(明显想骗吻,流氓。。。)所以这个题转化为计算怎么放不进一个盘子,相切是为是否能放进的边界条件
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> using namespace std; int main() { int t,kase=0; scanf("%d",&t); while (t--) { int n; double a,r; scanf("%d%lf%lf",&n,&a,&r); printf("Case #%d:\n",++kase); double x=(90*n-180)/n; double l=a/2*tan(x/180*3.1415926); if (l<r) printf("I want to kiss you!\n"); else printf("Give me a kiss!\n"); } return 0; }
3、列变位法解密
分析:直接模拟 AC
#include <cstdio> #include <cstring> #include <iostream> #include <string> #include <algorithm> using namespace std; const int maxn=1e5+5; int main() { int t,k; int g=0; scanf("%d",&t); char str[maxn]; int vis[maxn]; string cnt; while (t--) { getchar(); gets(str); int len=strlen(str); scanf("%d",&k); memset(vis,0,sizeof(vis)); int i=0; int n=len/k; int m=len%k; string sum=""; while (!vis[i] && i < len) { int j=i; cnt=""; cnt+=str[i]; vis[j]=1; for (int l=0;l<m;l++) { j=j+n+1; if (vis[j]) continue; if (j>=len) break; cnt+=str[j]; vis[j]=1; } for (int l=0;l<k-m;l++) { j+=n; if (vis[j]) continue; if (j>=len) break; cnt+=str[j]; vis[j]=1; } sum+=cnt; i++; } cout<<"Case #"<<++g<<":"<<endl; cout<<sum<<endl; } return 0; }
4、IP聚合
分析:用<set>容器,写几个运算符重载便可以,<map>死数次,悲哀
/*#include <cstdio> //失败代码LTE #include <map> #include <string> #include <cstring> #include <iostream> #include <algorithm> string ToString(int n) { string tmp=""; while (n) { tmp+=n%10+'0'; n/=10; } return tmp; } int main() { int t,m,n; scanf("%d",&t); while (t--) { map <string,int> p; p.clear(); scanf("%d%d",&n,&m); for (int i=0;i<n;i++) { scanf("%d.%d.%d.%d",&a1[i],&a2[i],&a3[i],&a4[i]); } for (int i=0;i<m;i++) { scanf("%d.%d.%d.%d",&b1[i],&b2[i],&b3[i],&b4[i]); } for (int i=0;i<n;i++) for (int j=0;j<m;j++) { int t1=a1[i]&b1[j]; int t2=a2[i]&b2[j]; int t3=a3[i]&b3[j]; int t4=a4[i]&b4[j]; string cnt=""; cnt=cnt+Tostring(t1)+ToString(t2)+ToString(t3)+ToString(t4); if (p.count(cnt) == 0) p[cnt]=1; } map<string,int>::iterator it=p.begin(); int tmp=0; for(;it!=p.end();it++) tmp++; printf("%d\n",tmp); } return 0; } */ //AC #include <iostream> #include <cstring> #include <cstdio> #include <set> using namespace std; int T,n,m; struct IP { int a,b,c,d; bool operator < (const IP &x) const { if (x.a!=a) return x.a<a; else if (x.b!=b) return x.b<b; else if (x.c!=c) return x.c<c; else return x.d<d; } IP operator & (IP &x) { IP y; y.a=x.a&a; y.b=x.b&b; y.c=x.c&c; y.d=x.d&d; return y; } }; set<IP> d; IP a[1005]; int main() { int Case=1; scanf("%d",&T); while (T--) { memset(a,0,sizeof(a)); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d.%d.%d.%d",&a[i].a,&a[i].b,&a[i].c,&a[i].d); printf("Case #%d:\n",Case++); for (int i=1;i<=m;i++) { int ans=0; IP c; scanf("%d.%d.%d.%d",&c.a,&c.b,&c.c,&c.d); d.clear(); for (int i=1;i<=n;i++) { IP f; f=a[i]&c; if (!d.count(f)) { ans++; d.insert(f); } } printf("%d\n",ans); } } return 0; }