the first CCPC   password 123

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/A

题意:给两个2*2的矩阵,问是否完全相同,其中一个矩阵可以旋转任意次90度。

解法:转4次都测一下是否相同。

 //#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e2+;
int a[M];
int b[M];
char str[][]={"POSSIBLE","IMPOSSIBLE"};
bool judge(int d){
for(int i=;i<;i++){
if(a[i]!=b[(i+d)%]) return false;
}
return true;
}
int solve(){
for(int i=;i<;i++){
if(judge(i)) return ;
}
return ;
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
while(~scanf("%d",&t)){
int cas=;
while(t--){
scanf("%d%d%d%d",&a[],&a[],&a[],&a[]);
scanf("%d%d%d%d",&b[],&b[],&b[],&b[]);
printf("Case #%d: %s\n",cas++,str[solve()]);
}
}
return ;
}

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/D

题意:将n个长度为a,价值为v的木棍放在长度为L的桌面上,其中两端的木棍只要保证中心在桌面上就行,问能得到的最大价值。

解法:就是01背包问题,只是其中有两个物体的花费可以除以2.下面用了一种非常不优美,但是比较好理解的dp,卡过。把所有长度*2避免浮点数。然后dp【i】【j】【k】表示前i个物品花费了j的长度有k个是减半的最大价值。i需要滚动。

 //#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e3+;
int a[M];
int v[M];
int n,L;
LL dp[][M<<][];
void init(int now){
for(int i=;i<=L;i++){
for(int j=;j<;j++){
dp[now][i][j]=-;
}
}
}
void Copy(int now,int pre){
for(int i=;i<=L;i++){
for(int j=;j<;j++){
dp[now][i][j]=dp[pre][i][j];
}
}
}
void update(int now,int i,int j,LL value){
dp[now][i][j]=max(dp[now][i][j],value);
}
LL solve(){
L<<=;
for(int i=;i<=n;i++){
a[i]<<=;
}
init();
dp[][][]=;
int now=;
int pre=;
for(int i=;i<=n;i++){
now^=;
pre^=;
Copy(now,pre);
for(int j=;j<=L;j++){
for(int k=;k<;k++){
LL &ans=dp[pre][j][k];
if(ans==-) continue;
if(j+a[i]<=L){
update(now,j+a[i],k,ans+v[i]);
}
if(k<&&j+(a[i]>>)<=L){
update(now,j+(a[i]>>),k+,ans+v[i]);
}
}
}
}
LL res=;
for(int i=;i<=n;i++){
res=max(res,0LL+v[i]);
}
for(int i=;i<=L;i++){
for(int j=;j<;j++){
res=max(res,dp[now][i][j]);
}
}
return res;
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
while(~scanf("%d",&t)){
int cas=;
while(t--){
scanf("%d%d",&n,&L);
for(int i=;i<=n;i++){
scanf("%d%d",&a[i],&v[i]);
}
printf("Case #%d: %lld\n",cas++,solve());
}
}
return ;
}

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/G

题意:给一盘围棋,XO分别是黑白棋,点是空的,问再放一个X能否杀掉一部分o,能杀就是o的连通块边缘没有空。

解法1:dfs出o的连通块,统计与之相邻的空格有几个,如果只有一个就可以杀。

 //#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e2+;
char a[M][M];
char str[][]={"Can kill in one move!!!","Can not kill in one move!!!"};
bool vis[M][M];
bool sum[M][M];
int dx[]={,,,-};
int dy[]={,-,,};
void init(bool v[M][M]){
for(int i=;i<;i++){
for(int j=;j<;j++){
v[i][j]=false;
}
}
}
bool inside(int x,int y){
return x>=&&x<&&y>=&&y<;
}
void dfs(int x,int y){
vis[x][y]=true;
for(int i=;i<;i++){
int tx=x+dx[i];
int ty=y+dy[i];
if(!inside(tx,ty)) continue;
if(vis[tx][ty]) continue;
if(a[tx][ty]=='x') continue;
if(a[tx][ty]=='.'){
sum[tx][ty]=true;
continue;
}
dfs(tx,ty);
}
}
bool can_kill(int sx,int sy){
init(sum);
dfs(sx,sy);
int res=;
for(int i=;i<;i++){
for(int j=;j<;j++){
if(sum[i][j]){
res++;
if(res>) return false;
}
}
}
return true;
}
int solve(){
init(vis);
for(int i=;i<;i++){
for(int j=;j<;j++){
if(vis[i][j]) continue;
if(a[i][j]!='o') continue;
if(can_kill(i,j)) return ;
}
}
return ;
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
while(~scanf("%d",&t)){
int cas=;
while(t--){
for(int i=;i<;i++){
scanf("%s",a[i]);
}
printf("Case #%d: %s\n",cas++,str[solve()]);
}
}
return ;
}

解法2:bfs出连通块,思路同上。

 //#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e2+;
char a[M][M];
char str[][]={"Can kill in one move!!!","Can not kill in one move!!!"};
bool vis[M][M];
bool sum[M][M];
int dx[]={,,,-};
int dy[]={,-,,};
struct Q{
int x,y;
}now,pre;
queue<Q> q;
void init(bool v[M][M]){
for(int i=;i<;i++){
for(int j=;j<;j++){
v[i][j]=false;
}
}
}
bool inside(int x,int y){
return x>=&&x<&&y>=&&y<;
}
void bfs(int x,int y){
vis[x][y]=true;
now.x=x;
now.y=y;
while(!q.empty()) q.pop();
q.push(now);
while(!q.empty()){
pre=q.front();
q.pop();
for(int i=;i<;i++){
int tx=pre.x+dx[i];
int ty=pre.y+dy[i];
if(!inside(tx,ty)) continue;
if(vis[tx][ty]) continue;
if(a[tx][ty]=='x') continue;
if(a[tx][ty]=='.'){
sum[tx][ty]=true;
continue;
}
vis[tx][ty]=true;
now.x=tx;
now.y=ty;
q.push(now);
}
}
}
bool can_kill(int sx,int sy){
init(sum);
bfs(sx,sy);
int res=;
for(int i=;i<;i++){
for(int j=;j<;j++){
if(sum[i][j]){
res++;
if(res>) return false;
}
}
}
return true;
}
int solve(){
init(vis);
for(int i=;i<;i++){
for(int j=;j<;j++){
if(vis[i][j]) continue;
if(a[i][j]!='o') continue;
if(can_kill(i,j)) return ;
}
}
return ;
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
while(~scanf("%d",&t)){
int cas=;
while(t--){
for(int i=;i<;i++){
scanf("%s",a[i]);
}
printf("Case #%d: %s\n",cas++,str[solve()]);
}
}
return ;
}

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/H

题意:给出4*4的矩阵,数字为1到4,*为未确定,给*赋值1到4,使得每行每列,四个角的2*2内都没有相同元素,保证唯一解。

解法1:把每一个位置可能的情况都存下set,每次出现只剩一个就说明该位置确定,然后将其所在行列块都删去这个数,直至推出答案。

 //#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e2+;
char a[M][M];
int b[M][M];
int dx[]={,,,};
int dy[]={,,,};
set<int> s[M][M];
void init(){
for(int i=;i<;i++){
for(int j=;j<;j++){
s[i][j].clear();
if(a[i][j]=='*'){
for(int k=;k<=;k++){
s[i][j].insert(k);
}
}
else{
s[i][j].insert(a[i][j]-'');
}
}
}
}
void Erase(int x,int y,int value){
for(int i=;i<;i++){
s[i][y].erase(value);
s[x][i].erase(value);
}
if(x&) x--;
if(y&) y--;
for(int i=;i<;i++){
int tx=x+dx[i];
int ty=y+dy[i];
s[tx][ty].erase(value);
}
}
void solve(){
init();
bool flag=true;
while(flag){
flag=false;
for(int i=;i<;i++){
for(int j=;j<;j++){
if(s[i][j].size()==){
flag=true;
b[i][j]=*s[i][j].begin();
Erase(i,j,b[i][j]);
}
}
}
}
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
while(~scanf("%d",&t)){
int cas=;
while(t--){
for(int i=;i<;i++){
scanf("%s",a[i]);
}
solve();
printf("Case #%d:\n",cas++);
for(int i=;i<;i++){
for(int j=;j<;j++){
printf("%d",b[i][j]);
}
puts("");
}
}
}
return ;
}

解法2:dfs每一个位置的取值,暴力所有情况。

 //#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e2+;
char a[M][M];
int b[M][M];
int dx[]={,,,};
int dy[]={,,,};
void init(){
for(int i=;i<;i++){
for(int j=;j<;j++){
b[i][j]=-;
if(a[i][j]!='*'){
b[i][j]=a[i][j]-'';
}
}
}
}
bool same(int x,int y,int value){
for(int i=;i<;i++){
if(b[x][i]==value) return true;
if(b[i][y]==value) return true;
}
if(x&) x--;
if(y&) y--;
for(int i=;i<;i++){
int tx=x+dx[i];
int ty=y+dy[i];
if(b[tx][ty]==value) return true;
}
return false;
}
bool dfs(int x,int y){
if(x==) return true;
if(y==) return dfs(x+,);
if(b[x][y]!=-) return dfs(x,y+);
for(int i=;i<=;i++){
if(same(x,y,i)) continue;
b[x][y]=i;
if(dfs(x,y+)) return true;
b[x][y]=-;
}
return false;
}
void solve(){
init();
dfs(,);
}
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
while(~scanf("%d",&t)){
int cas=;
while(t--){
for(int i=;i<;i++){
scanf("%s",a[i]);
}
solve();
printf("Case #%d:\n",cas++);
for(int i=;i<;i++){
for(int j=;j<;j++){
printf("%d",b[i][j]);
}
puts("");
}
}
}
return ;
}

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/L

题意:给n种字母,问组成最短的回文串的长度。

解法:n*2-1。

 //#define debug
//#define txtout
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const double eps=1e-;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int M=1e5+;
int a[M];
int main(){
#ifdef txtout
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t,n;
while(~scanf("%d",&t)){
int cas=;
while(t--){
scanf("%d",&n);
printf("Case #%d: %d\n",cas++,n*-);
}
}
return ;
}

end

matrix_last_acm_3的更多相关文章

随机推荐

  1. 强大的网络通信框架(实现缓存)--第三方开源--volley

    Android Volley是Android平台上很好用的第三方开源网络通信框架.使用简答,功能强大. Android Volley的库jar包Volley.ja下载连接地址:Volley下载 下载后 ...

  2. BAT命令介绍【转自Internet】

    一.简单批处理内部命令简介 1.Echo 命令 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo 命令将显示当前回显设置. 语法: echo [{on│off}] [message] ...

  3. Delphi开发的IP地址修改工具

    用Delphi进行开发的,直接修改注册表,需重启电脑后才生效

  4. Sorl之.net操作

    http://www.cnblogs.com/zhangweizhong/category/771055.html 插入: SolrNet.Startup.Init<Movie>(&quo ...

  5. 数据结构学习笔记05图(最小生成树 Prim Kruskal)

    最小生成树Minimum Spanning Tree 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 树: 无回路   |V|个顶 ...

  6. MongoDB复制机制实例

    MongoDB的主从复制是一个主可以多从已从又可以为主进行主从复制.在这里就是实现一主一从一个仲裁服务器使用一个数据库服务器通过提供不同的端口. 一.启动一个MongoDB服务名字是applicati ...

  7. 数据库事务故障恢复undo日志检查点

      checkpoint 检查点 checkpoint,即检查点.在undolog中写入检查点,表示在checkpoint前的事务都已经完成commit或者rollback 了,也就是检查点前面的事务 ...

  8. golang的并发

    Golang的并发涉及二个概念: goroutine channel goroutine由关键字go创建. channel由关键字chan定义 channel的理解稍难点, 最简单地, 你把它当成Un ...

  9. MongoDB学习笔记-数据库命令

    概念 数据库命令(database command)是一种非常特殊类型的查询.文档的创建.更新.删除及查询都属于数据库命令的范畴,它还包含管理性的任务(比如关闭服务器和克隆数据库).统计数据及执行聚合 ...

  10. 元音字母A的发音规则

    摘抄自百度文库 A/a的发音比较复杂,归纳起来有10种情况: 一.在重读开音节中读[ei]. 例如: plane [plein]  radio [ˈreidiəu] wake [weik]  pape ...