第一题是非常基础的一道模拟题,只是要注意下标的对应关系,nothing to say...(听说有大哥3个小时手推打表也是很服气...)
第二题需要求出图中的最小环,显然tarjan是很优的(而且很裸..),然而...我忘了...其实这道题也可以不用tarjan,但是思维有点僵化了,碰到熟悉的题目但对方法陌生可以尝试用方法的思路自己推导使用的方法!! 同时以前的东西要经常复习...
第三题斗地主,一道大模拟。贪心+搜索。这类题的思路一定不要怕麻烦,不要老想着如何写出最简代码,而是应该考虑让电脑枚举然后比较,这是模拟题非常精髓的一点,人在做题的时候每一步都想的是相对最优解,但让电脑来做则大可不必如此,有可能就算,算完比较就好了。当然了,有些非常明显的无意义计算能省则省。这类搜索型模拟还要多加练习..
代码:(洛谷2668)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[25],ans;
bool check(){
for(int i = 1;i <= 15;i++){
if(a[i]) return 0;
}
return 1;
}
int min(int a,int b){
if(a > b) return b;
return a;
}
void dfs(int dep){
if(dep > ans) return ;
if(check()){
ans = min(dep,ans);
}
int sum = 0;
for(int i = 1;i <= 13;i++){
if(a[i]) sum++;
}
if(a[14] + a[15]) sum++;
ans = min(ans,dep+sum);
for(int kind = 1;kind <= 5;kind++){
if(kind == 1){
for(int i = 1;i <= 8;i++){
if(a[i]){
bool flag = 1;
for(int j = i + 1;j <= i + 3;j++){
if(!a[j]){
flag = 0;
break;
}
}
if(!flag) continue;
for(int j = i + 4;j < 13&&a[j];j++){
for(int k = i;k <= j;k++) a[k]--;
dfs(dep+1);
for(int k = i;k <= j;k++) a[k]++;
}
}
}
}
if(kind == 2){
for(int i = 1;i <= 10;i++){
if(a[i]>=2&&a[i+1]>=2){
for(int j = i+2;j < 13&&a[j]>=2;j++){
for(int k = i;k <= j;k++) a[k]-=2;
dfs(dep+1);
for(int k = i;k <= j;k++) a[k]+=2;
}
}
}
}
if(kind == 3){
for(int i = 1;i <= 11;i++){
if(a[i] >= 3){
for(int j = i+1;j < 13&&a[j] >= 3;j++){
for(int k = i;k <= j;k++) a[k]-=3;
dfs(dep+1);
for(int k = i;k <= j;k++) a[k]+=3;
}
}
}
}
if(kind == 4){
for(int i = 1;i <= 13;i++){
if(a[i] >= 3){
a[i]-=3;
for(int j = 1;j <= 15;j++){
if(a[j]){
a[j]--;
dfs(dep+1);
a[j]++;
}
}
for(int j = 1;j <= 15;j++){
if(a[j] >= 2){
a[j] -= 2;
dfs(dep+1);
a[j] += 2;
}
}
a[i]+=3;
}
}
}
if(kind == 5){
for(int i = 1;i <= 13;i++){
if(a[i] >= 4){
a[i] -= 4;
for(int j = 1;j <= 15;j++){
if(a[j]){
a[j]--;
for(int k = 1;k <= 15;k++){
if(a[k]){
a[k]--;
dfs(dep+1);
a[k]++;
}
}
a[j]++;
}
}
a[i] += 4;
}
}
for(int i = 1;i <= 13;i++){
if(a[i] >= 4){
a[i] -= 4;
for(int j = 1;j <= 15;j++){
if(a[j] >= 2){
a[j] -= 2;
for(int k = 1;k <= 15;k++){
if(a[k] >= 2){
a[k] -= 2;
dfs(dep+1);
a[k] += 2;
}
}
a[j] += 2;
}
}
a[i] += 4;
}
}
}
}
}
int main(){
freopen("landlords.in","r",stdin);
freopen("landlords.out","w",stdout);
int t,n,x,y;
scanf("%d%d",&t,&n);
for(int p = 1;p <= t;p++){
memset(a,0,sizeof(a));
for(int i = 1;i <= n;i++){
scanf("%d%d",&x,&y);
if(!x) a[y+13]++;
if(x == 1||x == 2) a[x+11]++;
else a[x-2]++;
}
for(int i = 1;i <= 13;i++){
if(a[i]) ans++;
}
if(a[14]+a[15]) ans++;
dfs(0);
printf("%d\n",ans);
}
return 0;
}