11月12日——离noip还有7天[云之彼端,约定的地方]

要死了!!我家庭作业还没有开始做……
不管了,NOIP更重要,贪心!
所以今天考得还算满意(毕竟最后一道题是原题),(不要说出来嘛……)
好了。今天的推荐——(莫名觉得博客主好做死)
没错,就是云之彼端 约定的地方,看了之后也是挺感动的,不算bad end也不算happy end。虽然画风“感人”,但是佳作终归是佳作。
图片就自己找吧……不给!
百度云:http://pan.baidu.com/s/1jIkCoJk

A

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

题解(过于简单)

Well,这道题是考的xxx。(貌似我猜出这份题解是谁出的了……)
我们来欣赏一下:
首先,为了方便描述,把题目要求的列 转化 为行,其实都一样的。
假设现在有12个人,于是就每一排站6个人就ok了。然后规定第2排的要比他对应的第1排的高。
Then给每一个人按照身高编号 1 2 3 4 5 6 7 8 9 10 11 12
我们若用0表示某人站第一排,1站第二排。
于是0 0 0 0 0 0 1 1 1 1 1 1
对应 1 2 3 4 5 6
7 8 9 10 11 12
还比如0 1 0 1 0 1 0 1 0 1 0 1
对应 1 3 5 7 9 11
2 4 6 8 10 12
按照题目描述
对于某个人而言 :
若他要站第一排 :
第一排前面的人必须比他矮
若他要站第二排
第二排前面的人必须比他矮&&他上面那个位置一定要站一个比他矮的人
所以
我们可以考虑按照从低到高次序的把人放进去。
这样考虑过后也就是说:
状态为 0 的人,直接往里面站就ok了
所有状态为 1 的人,在他的上面必须找到一个状态为0的人

若我们把 0 看做 进栈 , 1 看做 出栈
于是题目变成了 求给定n个元素有多少种进出栈方式。
于是就是我们做过的 卡特兰数 了。
然而:曾逸强大的手推+DYJ维基百科上秀了一些公式+我们其实用这些公式AC了当时的那到题目。所以从某种层面上来讲,我们是学过并用过的。
好的:

70分以下做法:
神奇的DFS可以搞,然而貌似只能过小数据

70分做法:
若有人只记得这个公式:
H(n) = C(2n,n)/(n+1)                //H(n) 表示 第n个卡特兰数
这个做法可以针对询问中的每一个N,求出答案。
因为 其中 2n是确定的 
然后 C(n,k+1) = C(n,k)*(n-k)/(k+1)  O(n)递推出C(2n,n)即可.
当然也可以用,YYR上次讲的那个长得像是(就是)等比数列的东西求,也是O(n)的。

其实不用这么麻烦,快速幂->逆元->卡特兰数就可以了

自己傲娇的code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define rez(i,x,y) for(int i=x;i>=y;i--)
#define res(i,x,y) for(int i=x;i<=y;i++)
#define INF 2100000000
#define ll long long
#define clr(x)  memset(x,0,sizeof(x))
#define NAME "a"
#define MOD 1000000009
using namespace std;
inline void readin(ll &res) {
  static char ch;
  while ((ch = getchar()) < '0' || ch > '9');
    res = ch - 48;
  while ((ch = getchar()) >= '0' && ch <= '9')
    res = res * 10 + ch - 48;
}
ll power_mod(ll x,ll y){
    ll ans=1;
    while(y>0){
        if(y%2==1)ans=(ans*x)%MOD;
        y/=2;
        x=(x*x)%MOD;
    }
    return ans;
}
ll a[2000005];
ll n,t; 
int main(){
    freopen(NAME".in","r",stdin);
    freopen(NAME".out","w",stdout);
    a[1]=1;
    for(int i=2;i<=2000000;i++){
        a[i]=(a[i-1]*i)%MOD;
    }
    readin(t);
    while(t--){
        readin(n);
        ll g1=power_mod(a[n/2],MOD-2);
        ll g2=power_mod(a[n/2+1],MOD-2);
        ll g=(g1*g2)%MOD;
        g=(a[n]*g)%MOD;
        cout<<g<<endl;
    }
    return 0;
}
//C(n,2n)/(n+1)=(2n!)/(n!*(n+1)!)
//卡特兰数 
//快速幂 

标答

#define PROB "zhandui"
#define INFILE "a.in"
#define OUTFILE "a.out"
#include <cstdio>
#include <algorithm>
using namespace std;

typedef unsigned long long uint64;
#ifdef WIN32
#   define Mui64 "%I64d"
#else
#   define Mui64 "%lld"
#endif

const int MaxT = 100100;
const int MaxN = 2000100;
const int Mod = 1000000009;
int T, q[MaxT], z;
uint64 C[MaxN];

uint64 inv[MaxN];
int p[MaxN], pi;
bool composite[MaxN];

uint64 modexp(uint64 b, uint64 e) {
    uint64 r = 1;
    for(; e > 0; e >>= 1, b = b * b % Mod)
        if(e & 1)
            r = r * b % Mod;
    return r;
}

void sieve(int n) {
    for(int s = 2; s <= n; ++s) {
        if(!composite[s]) {
            p[pi++] = s;
            inv[s] = modexp(s, Mod - 2);
        }
        for(int i = 0; i < pi && s * p[i] <= n; ++i) {
            composite[s * p[i]] = true;
            inv[s * p[i]] = inv[s] * inv[p[i]] % Mod;
        }
    }
}

int main() {
    freopen(INFILE, "r", stdin);
    freopen(OUTFILE, "w", stdout);

    scanf("%d", &T);
    for(int i = 0; i < T; ++i) {
        scanf("%d", &q[i]);
        q[i] /= 2;
        z = max(z, q[i]);
    }
    sieve(z + 12);

    C[0] = 1;
    for(int n = 1; n <= z; ++n)
        C[n] = (C[n - 1] * (4 * n - 2) % Mod) * inv[n + 1] % Mod;

    for(int i = 0; i < T; ++i)
        printf("%d\n", static_cast<int>(C[q[i]]));
    return 0;
}

B

这里写图片描述
这里写图片描述
所以说直接贪心or暴力就可以过的题,我求稳不用dp(貌似哪里反了吧……)

题解

1

这里写图片描述

2

不知道为何O(mn^2)居然可以过!!!
好吧,用优先队列存值然后贪心就可以了。
为dp大神们ORZ……

dp解

#include <iostream>

using namespace std;
const int maxn=1055;
long long dp[maxn][maxn];
int a[maxn];
int work(long long num,int r)
{
    int l=0,ans;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(dp[1][mid]+num>=0){
            ans=mid;r=mid-1;
        }
        else l=mid+1;
    }
    return ans;
}
int main() {
   freopen("b.in","r",stdin);
  freopen("b.out","w",stdout);  
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",a+i);
    dp[n+1][0]=0;
    for(int i=n;i;i--)
    {
        dp[i][0]=min(1LL*a[i],dp[i+1][0]+a[i]);
        dp[i][n-i+1]=0;
        for(int j=1;j<n-i+1;j++)
        {
            dp[i][j]=min(a[i]+dp[i+1][j],1LL*a[i]);
            dp[i][j]=max(dp[i][j],dp[i+1][j-1]);
        }
    }
    while(m--)
    {
        long long x;
        scanf("%I64d",&x);
        printf("%d\n",work(x,n));
    }
    return 0;
}

某大神手写”优先队列“

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
template <class T> inline void read(T &x)
{
    x = 0;
    register T flag = 1;
    register char ch = (char)getchar();
    while(ch<'0' || ch>'9')
    {
        if(ch == '-') flag = -1;
        ch = (char)getchar();
    }
    while(ch>='0' && ch<='9')
    {
        x = (x<<1) + (x<<3) + ch - '0';
        ch = (char)getchar();
    }
    x *= flag;
}
template <class T> T gcd(T a,T b) { return !b?a:gcd(b,a%b); }
const int INF=0x3f3f3f3f;
const int maxn = 1005;
int a[maxn];
int n,q;
inline void init()
{
    read(n); read(q);
    for(register int i=1;i<=n;i++) read(a[i]);
}
int que[maxn],maxnode;
inline void push(const int x)
{
    que[++maxnode] = x;
    int root = maxnode;
    while(root > 1)
    {
        if(que[root] <= que[root>>1]) break;
        swap(que[root],que[root>>1]);
        root >>= 1;
    }
}
inline int pop()
{
    int ret = que[1];
    que[1] = que[maxnode--];
    int root = 1;
    while(root < maxnode)
    {
        int nxt = root<<1;
        if(nxt > maxnode) break;
        if((nxt|1)<=maxnode && que[nxt]<que[nxt|1]) nxt|=1;
        if(que[root] >= que[nxt]) break;
        swap(que[root],que[nxt]);
        root = nxt;
    }
    return ret;
}
inline int Greedy()
{
    maxnode=0;
    int ans = 0;
    LL cur; read(cur);
    for(register int i=1;i<=n;i++)
    {
        if(a[i]<0) push(-a[i]);
        cur += a[i];
        if(cur < 0) ans++,cur+=pop();
    }
    return ans;
}
int main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    init();
    while(q--) printf("%d\n",Greedy());
    return 0;
}

张*飞的贪心

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int n,m;
int a[1005];
struct node{
    int w,pos;
}b[1005][1005];
int vis[1005];
bool comp(const node &r,const node &t)
{
    if(r.w==t.w)return r.pos<t.pos;
    return r.w<t.w;
}
int temp=0;
int main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        temp=0;
        for(int j=1;j<=i;j++)
        if(a[j]<0)
        {
            b[i][++temp].w=a[j];
            b[i][temp].pos=j;
        }
        sort(b[i]+1,b[i]+temp+1,comp);
    }
    for(int i=1;i<=m;i++)
    {
        int ans=0;
        int prepos=0,pretemp=0;
        b[0][0].w=1;
        int x;scanf("%d",&x);
        memset(vis,0,sizeof(vis));
        for(int j=1;j<=n;j++)
        {
            x+=a[j];
            if(x>=0)continue;
            int temp1=1;
            if(b[j][1].w<b[prepos][1].w)
            {
                vis[b[j][1].pos]=true;
                x-=b[j][1].w;ans++;
                prepos=j;pretemp=1;
                continue;
            }
            else
            {
                while(vis[b[j][temp1].pos]==true)temp1++;
                vis[b[j][temp1].pos]=true;
                x-=b[j][temp1].w;ans++;
                prepos=j;pretemp=temp1;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

C

这里写图片描述
【问题描述】
小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低。但普通的数独对他们来说都过于简单了,于是他们向Z博士请教,Z博士拿出了他最近发明的“靶形数独”,作为这两个孩子比试的题目。
靶形数独的方格同普通数独一样,在9格宽×9格高的大九宫格中有9个3格宽×3格高的小九宫格(用粗黑色线隔开的)。在这个大九宫格中,有一些数字是已知的,根据这些数字,利用逻辑推理,在其他的空格上填入1到9的数字。每个数字在每个小九宫格内不能重复出现,每个数字在每行、每列也不能重复出现。但靶形数独有一点和普通数独不同,即每一个方格都有一个分值,而且如同一个靶子一样,离中心越近则分值越高。(如图)

这里写图片描述
上图具体的分值分布是:最里面一格(黄色区域)为10分,黄色区域外面的一圈(红色区域)每个格子为9分,再外面一圈(蓝色区域)每个格子为8分,蓝色区域外面一圈(棕色区域)每个格子为7分,最外面一圈(白色区域)每个格子为6分,如上图所示。比赛的要求是:每个人必须完成一个给定的数独(每个给定数独有可能有不同的填法),而且要争取更高的总分数。而这个总分数即每个方格上的分值和完成这个数独时填在相应格上的数字的乘积的总和。如图,在以下这个已经填完数字的靶形数独游戏中,总分为2829。游戏规定,将以总分数的高低决出胜负。
这里写图片描述
由于求胜心切,小城找到了善于编程的你,让你帮他求出,对于给定的靶形数独,能够得到的最高分数。

【输入】
输入文件名为c.in。
一共9行,每行9个整数(每个数都在0—9的范围内),表示一个尚未填满的数独方格,未填满的空格用“0”表示。每两个数字之间用一个空格隔开。

【输出】
输出文件c.out共1行。
输出可以得到的靶形数独的最高分数。如果这个数独无解,则输出整数-1。

【输入输出样例1】
c.in
7 0 0 9 0 0 0 0 1
1 0 0 0 0 5 9 0 0
0 0 0 2 0 0 0 8 0
0 0 5 0 2 0 0 0 3
0 0 0 0 0 0 6 4 8
4 1 3 0 0 0 0 0 0
0 0 7 0 0 2 0 9 0
2 0 1 0 6 0 8 0 4
0 8 0 5 0 4 0 1 2
c.out
2829

【输入输出样例2】

c.in
0 0 0 7 0 2 4 5 3
9 0 0 0 0 8 0 0 0
7 4 0 0 0 5 0 1 0
1 9 5 0 8 0 0 0 0
0 7 0 0 0 0 0 2 5
0 3 0 5 7 9 1 0 8
0 0 0 6 0 1 0 0 0
0 6 0 9 0 0 0 0 1
0 0 0 0 0 0 0 0 6
c.out
2852

【数据范围】
40%的数据,数独中非0数的个数不少于30。
80%的数据,数独中非0数的个数不少于26。
100%的数据,数独中非0数的个数不少于24。

thought

就是考搜索加自己的各种优化。。。。。。
于是我差点用随机数了……
还是正常地用位运算AC吧……

自己的渣渣代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define rez(i,x,y) for(int i=x;i>=y;i--)
#define res(i,x,y) for(int i=x;i<=y;i++)
#define INF 2100000000
#define ll long long
#define clr(x)  memset(x,0,sizeof(x))
#define NAME "c"
#define con(i) (1<<(i))
#define id(i,j) ((i)/3*3+(j)/3)
#define order(i,j) (3*((i)-(i)/3*3)+(j)-(j)/3*3)
using namespace std;
//貌似是noip2009的原题,我当时就被这巧妙的位运算给吓到了…… 
inline void readin(int &res) {
  static char ch;
  while ((ch = getchar()) < '0' || ch > '9');
    res = ch - 48;
  while ((ch = getchar()) >= '0' && ch <= '9')
    res = res * 10 + ch - 48;
}
int mp[11][11],row[9];
int lie[9],line[9],ma[9];
int f[512],ans;
int node[9],cnt[9];
int fin;
int sore[9][9]={{6, 6, 6, 6,  6, 6, 6, 6, 6},
                {6, 7, 7, 7,  7, 7, 7, 7, 6},
                {6, 7, 8, 8,  8, 8, 8, 7, 6},
                {6, 7, 8, 9,  9, 9, 8, 7, 6},
                {6, 7, 8, 9, 10, 9, 8, 7, 6},
                {6, 7, 8, 9,  9, 9, 8, 7, 6},
                {6, 7, 8, 8,  8, 8, 8, 7, 6},
                {6, 7, 7, 7,  7, 7, 7, 7, 6},
                {6, 6, 6, 6,  6, 6, 6, 6, 6}};
void grade(){
    int t=0;
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            t+=mp[i][j]*sore[i][j];
        }
    }
    if(ans<t)ans=t;
}
void search(int now){
    int i,j,p;
    int pos,k;
    if(now==9){
        grade();
        return;
    }
    i=node[now];
    if(cnt[i]==0){
        search(now+1);
        return;
    }
    cnt[i]--;
    p=511^row[i];
    p=p&-p;
    row[i]|=p;
    j=f[p];
    pos=511^(lie[i]|line[j]|ma[id(i, j)]);
    while(pos>0){
        k=pos&-pos;
        pos^=k;
        lie[i]|=k;
        line[j]|=k;
        ma[id(i,j)]|=k;
        mp[i][j]=f[k]+1;
        search(now);
        lie[i]^=k;
        line[j]^=k;
        ma[id(i,j)]^=k;
    }
    cnt[i]++;
    row[i]^=p;
}
int main(){ 
    int t=0;
    freopen(NAME".in","r",stdin);
    freopen(NAME".out","w",stdout);
    for(int i=1,j=0;i<=511;i<<=1,j++){
        f[i]=j;
    }
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            cin>>mp[i][j];
            if(mp[i][j]!=0){
                row[i]|=con(j);
                t=con(mp[i][j]-1);
                if(((lie[i]&t)!=0)||((line[j]&t)!= 0)||((ma[id(i,j)]&t)!=0)){
                    cout<<-1<<endl;
                    return 0;
                }
                lie[i]|=t;
                line[j]|=t;
                ma[id(i,j)]|=t;
            }else{
                cnt[i]++;
            }
        }
    }
    for(int i=0;i<9;i++)node[i]=i;
    for(int i=0;i<9;i++){
        for(int j=i+1;j<9;j++){
            if(cnt[node[i]] > cnt[node[j]]){
                node[i]^=node[j];
                node[j]^=node[i];
                node[i]^=node[j];
            }
        }
    }
    int tot=0;
    while(cnt[node[tot]]==0)tot++;
    search(tot);
    if(ans==0){
        cout<<-1<<endl;
        return 0;
    }   
    cout<<ans<<endl;
    return 0;
}

何神的舞蹈链

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
template <class T> inline void read(T &x)
{
    x = 0;
    T flag = 1;
    char ch = (char)getchar();
    while(ch<'0' || ch>'9')
    {
        if(ch == '-') flag = -1;
        ch = (char)getchar();
    }
    while(ch>='0' && ch<='9')
    {
        x = (x<<1) + (x<<3) + ch - '0';
        ch = (char)getchar();
    }
    x *= flag;
}
template <class T> T gcd(T a,T b) { return !b?a:gcd(b,a%b); }
const int INF=0x3f3f3f3f;
const int maxrow = 9*9*9+5;
const int maxcol = 4*9*9+5;
const int maxn = maxrow*maxcol;
struct Node
{
    int left,right,up,down;
    int row,col;
}node[maxn];
#define left(x) node[x].left 
#define right(x) node[x].right
#define up(x) node[x].up
#define down(x) node[x].down
#define row(x) node[x].row
#define col(x) node[x].col
int rows,cols;
int maxnode,mustselect;
int tot[maxcol];
int head;
inline void disable_row(int root)
{
    left(right(root)) = left(root);
    right(left(root)) = right(root);
}
inline void disable_col(int root)
{
    up(down(root)) = up(root);
    down(up(root)) = down(root);
}
inline void enable_row(int root)
{
    left(right(root)) = root;
    right(left(root)) = root;
}
inline void enable_col(int root)
{
    up(down(root)) = root;
    down(up(root)) = root;
}
inline void remove(int colnum)
{
    disable_row(colnum);
    for(int i=down(colnum);i^colnum;i=down(i))
        for(int j=right(i);j^i;j=right(j))
            disable_col(j),tot[col(j)]--;
}
inline void restore(int colnum)
{
    enable_row(colnum);
    for(int i=up(colnum);i^colnum;i=up(i))
        for(int j=left(i);j^i;j=left(j))
            enable_col(j),tot[col(j)]++;
}
inline void initialize()
{
    memset(node,0,sizeof(node));
    memset(tot,0,sizeof(tot));
    rows=0; cols=4*9*9;
    head=0;
    left(head)=cols; right(head)=1;
    for(int i=1;i<=cols;i++)
    {
        left(i) = i-1;
        right(i) = i+1;
        up(i) = i;
        down(i) = i;
        row(i) = 0;
        col(i) = i;
    }
    right(cols) = head;
    maxnode=cols;
    mustselect = 0;
}
struct Info
{
    int x,y;
    int num;
    Info(const int _x = 0,const int _y = 0,const int _num = 0)
    {
        x=_x; y=_y; num=_num;
    }
}val[maxrow];
int a[maxcol];
Info ans[maxrow];
int top;
void add_row(int a[maxcol],int cnt,Info info)
{
    rows++;
    val[rows] = info;
    for(int i=1;i<=cnt;i++)
    {
        maxnode++;
        tot[a[i]]++;
        if(i==1)
        {
            left(maxnode) = maxnode;
            right(maxnode) = maxnode;
        }
        else
        {
            left(maxnode) = maxnode-1;
            right(maxnode) = right(maxnode-1);
            enable_row(maxnode);
        }
        up(maxnode) = up(a[i]);
        down(maxnode) = a[i];
        enable_col(maxnode);
        col(maxnode) = a[i];
        row(maxnode) = rows;
    }
}
void insert_num(int i,int j,int num)
{
    int N = (i-1)/3*3 + (j-1)/3 + 1;
    a[1] = (i-1)*9 + j;
    a[2] = (i-1)*9 + num + 81;
    a[3] = (j-1)*9 + num + 162;
    a[4] = (N-1)*9 + num + 243;
    add_row(a,4,Info(i,j,num));
    ans[mustselect++] = val[rows];
    for(int i=1;i<=4;i++) tot[a[i]]=-1,remove(a[i]);
}
void insert_empty(int i,int j)
{
    int N = (i-1)/3*3 + (j-1)/3 + 1;
    a[1] = (i-1)*9 + j;
    a[2] = (i-1)*9 + 81;
    a[3] = (j-1)*9 + 162;
    a[4] = (N-1)*9 + 243;
    for(int k=1;k<=9;k++)
    {
        a[2]++; a[3]++; a[4]++;
        bool flag=true;
        for(int p=1;p<=4;p++)
            if(!~tot[a[p]]) flag=false;
        if(flag) add_row(a,4,Info(i,j,k));
    }
}
const int VAL[10][10] =
{
    {},
    {0,6,6,6,6,6,6,6,6,6},
    {0,6,7,7,7,7,7,7,7,6},
    {0,6,7,8,8,8,8,8,7,6},
    {0,6,7,8,9,9,9,8,7,6},
    {0,6,7,8,9,10,9,8,7,6},
    {0,6,7,8,9,9,9,8,7,6},
    {0,6,7,8,8,8,8,8,7,6},
    {0,6,7,7,7,7,7,7,7,6},
    {0,6,6,6,6,6,6,6,6,6}
};
int g[100][100];
int ANS;
bool flag;
void update()
{
    flag = true;
    memset(g,0,sizeof(g));
    for(int i=0;i<top;i++)
    {
        Info tmp = ans[i];
        g[tmp.x][tmp.y] = tmp.num;
    }
    int now = 0;
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
            now += VAL[i][j] * g[i][j];
    smax(ANS,now);
}
void Dance(int k)
{
    int c1 = right(head);
    if(c1 == head)
    {
        top = k;
        update();
        return;
    }
    for(int i=right(c1);i^head;i=right(i))
    {
        if(tot[i] < tot[c1]) c1 = i;
        if(!tot[i]) return;
    }
    remove(c1);
    for(int i=down(c1);i^c1;i=down(i))
    {
        ans[k] = val[row(i)];
        for(int j=right(i);j^i;j=right(j)) remove(col(j));
        Dance(k+1);
        for(int j=left(i);j^i;j=left(j)) restore(col(j));
    }
    restore(c1);
}
const int maxlen = 11;
int graph[maxlen][maxlen];
void init()
{
    initialize();
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
            read(graph[i][j]);
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
            if(graph[i][j]) insert_num(i,j,graph[i][j]);
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
            if(!graph[i][j]) insert_empty(i,j);
}
int main()
{
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    init();
    Dance(mustselect);
    if(flag) printf("%d",ANS);
    else printf("-1");
    return 0;
}

HAHA

(今天的三张图片是一套……)
感觉内心崩溃了……
lemonoil大约的确死了……

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值