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;
}