BOJ 429 学姐的数码管
解题报告:纯模拟,提供两种思路
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
int n;
char m[10];
int main()
{
while(~scanf("%d ",&n))
{
gets(m);
int first=1,len=strlen(m);
for(int i=0;i<2*n+1;i++) //i表示行数
{
for(int j=0;j<len;j++) //j表示在该位置的数字
{
switch(m[j])
{
case '0':
if(i==0||i==2*n)
for(int k=0;k<n;k++)
printf("#");
else
{
printf("#");
for(int k=1;k<n-1;k++)
printf(" ");
printf("#");
}
break;
case '1':
for(int k=0;k<n-1;k++)
printf(" ");
printf("#");
break;
case '2':
if(i==0||i==n||i==2*n)
for(int k=0;k<n;k++)
printf("#");
else if(i<n)
{
for(int k=0;k<n-1;k++)
printf(" ");
printf("#");
}
else
{
printf("#");
for(int k=0;k<n-1;k++)
printf(" ");
}
break;
case '3':
if(i==0||i==n||i==2*n)
for(int k=0;k<n;k++)
printf("#");
else
{
for(int k=0;k<n-1;k++)
printf(" ");
printf("#");
}
break;
case '4':
if(i<n)
{
printf("#");
for(int k=1;k<n-1;k++)
printf(" ");
printf("#");
}
else if(i==n)
for(int k=0;k<n;k++)
printf("#");
else
{
for(int k=0;k<n-1;k++)
printf(" ");
printf("#");
}
break;
case '5':
if(i==0||i==n||i==2*n)
for(int k=0;k<n;k++)
printf("#");
else if(i>n)
{
for(int k=0;k<n-1;k++)
printf(" ");
printf("#");
}
else
{
printf("#");
for(int k=0;k<n-1;k++)
printf(" ");
}
break;
case '6':
if(i==0||i==n||i==2*n)
for(int k=0;k<n;k++)
printf("#");
else if(i<n)
{
printf("#");
for(int k=0;k<n-1;k++)
printf(" ");
}
else
{
printf("#");
for(int k=1;k<n-1;k++)
printf(" ");
printf("#");
}
break;
case '7':
if(i==0)
for(int k=0;k<n;k++)
printf("#");
else
{
for(int k=0;k<n-1;k++)
printf(" ");
printf("#");
}
break;
case '8':
if(i==0||i==n||i==2*n)
for(int k=0;k<n;k++)
printf("#");
else
{
printf("#");
for(int k=1;k<n-1;k++)
printf(" ");
printf("#");
}
break;
case '9':
if(i==0||i==n||i==2*n)
for(int k=0;k<n;k++)
printf("#");
else if(i>n)
{
for(int k=0;k<n-1;k++)
printf(" ");
printf("#");
}
else
{
printf("#");
for(int k=1;k<n-1;k++)
printf(" ");
printf("#");
}
break;
case '.':
if(i!=2*n)
printf(" ");
else
printf("#");
}
if(j==len-1)
printf("\n");
else
printf(" ");
}
}
puts("");
}
return 0;
}
S神的状态压缩代码
详见:http://blog.csdn.net/birdstorm_s/article/details/38146589
</pre><pre name="code" class="cpp">/*
USER_ID: test#weak_chicken
PROBLEM: 429
SUBMISSION_TIME: 2014-07-19 11:16:12
*/
#include <cstdio>
#include <cstring>
#include <cctype>
#define pw printf(w?"#":" ")
#define ph printf(h?"#":" ")
#define pb printf(g?"#":" ")
using namespace std;
int main()
{
int i, p, q, j, w, h, g, t, n, dig[10], cp[5][2]={3,5,2,4,26,44,16,32,80,96};
bool st=false;
char s[10], num[11]="w$]m.k{%o";
while(~scanf("%d%s",&n,s)){
int len=strlen(s), top=0, dot=-1;
if(st) puts("");
else st=true;
for(i=0; i<len; i++)
if(isdigit(s[i])) dig[top++]=num[s[i]-'0'];
else dot=top;
for(i=0, p=q=n-2; i<5; i++){
for(j=0; j<top; j++){
t=dig[j]; w=t&cp[i][0], h=t&cp[i][1];
if(j) printf(j==dot?(i==4?" # ":" "):" ");
g=!(i&1)&&t&(1<<(i*3/2));
pw; for(int k=1; k<n-1; k++) pb; ph;
}
if(i==1&&p) i--,p--;
if(i==3&&q) i--,q--;
puts("");
}
}
return 0;
}
BOJ 430 学姐的旋转图像
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
template<class T>
inline bool read(T &n)
{
T x = 0, tmp = 1; char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
int n,m,k;
int mapp[550][550];
int main()
{
while(read(n)&&read(m)&&read(k))
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
read(mapp[i][j]);
k/=90;
k%=4;
switch(k)
{
case 0:
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
printf("%d%c",mapp[i][j],j!=m-1? ' ':'\n');
break;
case 3:
for(int j=m-1;j>=0;j--)
for(int i=0;i<n;i++)
printf("%d%c",mapp[i][j],i!=n-1? ' ':'\n');
break;
case 2:
for(int i=n-1;i>=0;i--)
for(int j=m-1;j>=0;j--)
printf("%d%c",mapp[i][j],j? ' ':'\n');
break;
case 1:
for(int j=0;j<m;j++)
for(int i=n-1;i>=0;i--)
printf("%d%c",mapp[i][j],i? ' ':'\n');
break;
}
}
return 0;
}
BOJ 409 数的关系
提供两种思路:
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
map<string,int> a;
int main()
{
std::ios::sync_with_stdio(false);//取消cin与scanf之间的同步,加快cin的速度,也可以先读取scanf再循环赋值给string
string c;
while(cin>>c)
{
printf("%d\n",++a[c]);
}
return 0;
}
HASH表:
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
template<class T>
inline bool read(T &n)
{
T x = 0, tmp = 1; char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
typedef unsigned long long ll;
const ll B = 13;
const int MAXN=1000;
vector<ll> a[MAXN];
ll Hash(char *str)//求字符串的hash值;
{
int len=strlen(str);
ll bh=0;
for(int i=0;i<len;i++)
bh=bh*B+str[i];
return bh;
}
int main()
{
char str[105];
while(~scanf("%s",str))
{
int sum=0;
ll hs=Hash(str);
int mod=hs%MAXN;
a[mod].push_back(hs);
for(int i=0;i<a[mod].size();i++)
if(a[mod][i]==hs)
sum++;
printf("%d\n",sum);
}
return 0;
}
BOJ 428 田田的账号
可以用打表,也可以用组合数学推,也可以用DP递推,找公式
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
template<class T>
inline bool read(T &n)
{
T x = 0, tmp = 1; char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
const int MOD=1000000007;
long long qpow(long long a,long long i)
{
if(i==0)
return 1;
long long temp=qpow(a,i>>1);
temp=(temp*temp)%MOD;
if(i&1)
temp=(temp*a)%MOD;
return temp;
}
int main()
{
int T,n;
read(T);
while(T--)
{
read(n);
n--;
printf("%lld\n",qpow(4,n));
}
return 0;
}
BOJ 419 学姐的数列
线段DP,dp[ i ][ j ][ w ]表示从 i 到 j 之间 和为 w 的满足题意的最长长度。
后面两篇皆出自学长之手:
第二篇略微神奇,第二篇bag[ i ]表示的所有和为 i 的满足题意的最长长度,其中 i 是利用位运算和二进制进行压缩,用lowbit表示低于 j 的某个状态,改状态必定可以通过以前的构造形成,在插入 a[ i ] 后达到状态 j ;
第三篇更神奇,不会
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
template<class T>
inline bool read(T &n)
{
T x = 0, tmp = 1; char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
//-------------------------------------------------------------------------
int a[150];
int dp[150][150][20];
int main()
{
int T,n;
read(T);
while(T--)
{
read(n);
for(int i=0;i<n;i++)
read(a[i]);
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
for(int j=i;j<n;j++)
for(int k=i;k<=j;k++)
dp[i][j][a[k]]=1;
for(int w=1;w<20;w++)
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
for(int k=i;k<j;k++)
{
if(!dp[i][k][w-1]||!dp[k+1][j][w-1])
continue;
if(dp[i][j][w]<dp[i][k][w-1]+dp[k+1][j][w-1])
dp[i][j][w]=dp[i][k][w-1]+dp[k+1][j][w-1];
}
int ans=0;
for(int i=0;i<20;i++)
if(ans<dp[0][n-1][i])
ans=dp[0][n-1][i];
printf("%d\n",ans);
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&-x)
using namespace std;
const int maxn=1<<14;
int bag[maxn+5],a[1<<7];
int main()
{
int t,n,i,j;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(bag,0,sizeof(bag));
bag[0]=1;
int ans=0;
for(i=0;i<n;i++){
scanf("%d",&a[i]);
int val=1<<a[i];
for(j=maxn;j>=val;j--)
if(bag[j-val]&&val<=lowbit(j))
bag[j]=max(bag[j],bag[j-val]+1);
}
for(i=1;i<=14;i++)
ans=max(ans,bag[1<<i]);
printf("%d\n",ans-1);
}
return 0;
}
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
#include<cstdlib>
#define ll long long
#define L 100050
#define N 1050
#define inf 999999999
#define pi acos(-1.0)
int dp[N*200],a[N],b[N],sum[N],ans,tot,cur,vis[N];
using namespace std;
int main(){
int i,j,k,len,t,n;
char str[L];
for(scanf("%d",&t);t--;){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]=(ll)pow(2,a[i]*1.0);
}
for(i=1;i<=n;i++){
vis[i]=1;
for(j=1;j<=n;j++)
if(i!=j&&a[i]%a[j]==0&&a[i]!=a[j]){
cur=a[i]/a[j];
if(((cur-1)&cur)==0){vis[i]=0;break;}
}
}
ans=0;
for(i=1;i<=n;i++)
if(vis[i]){
tot=0;
for(j=1;j<=n;j++)
if(a[j]%a[i]==0){
cur=a[j]/a[i];
if(((cur-1)&cur)==0)b[++tot]=cur;
}
for(j=1;j<=tot;j++)sum[j]=sum[j-1]+b[j];
for(j=0;j<=sum[tot];j++)dp[j]=-inf;
dp[0]=0;
for(j=1;j<=tot;j++)
for(k=sum[j];k>=b[j];k--)
if(((k-b[j])&(b[j]-1))==0)
dp[k]=max(dp[k],dp[k-b[j]]+1);
for(j=1;j<=sum[tot];j++)
if(dp[j]>0&&((j-1)&j)==0)ans=max(ans,dp[j]);
for(j=1;j<=n;j++)
if(a[i]==a[j])vis[j]=0;
}
printf("%d\n",ans);
}
return 0;
}