Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"sort"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)
const INF = 0x7fffffff
func main() {
	scanner.Scan()
	n, _ := strconv.Atoi(scanner.Text())
	top := make([]int, 0)
	bottom := make([]int, 0)
	for i := 0; i < n; i++ {
		scanner.Scan()
		buf := strings.Split(scanner.Text(), " ")
		a, _ := strconv.Atoi(buf[0])
		b, _ := strconv.Atoi(buf[1])
		top = append(top, a)
		bottom = append(bottom, b)
	}
	dp := make([][]int, n+1)
	for i := range dp {
		dp[i] = make([]int, n+1)
	}
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			dp[i][j] = INF
		}
	}
	for j := 0; j < n; j++ {
		dp[0][j] = 0
	}
	for i := 1; i < n; i++ {
		for j := 0; j < n-i; j++ {
			tmp := make([]int, 0)
			for k := 0; k < i; k++ {
				tmp = append(tmp, dp[k][j] + dp[i - k - 1][j + k + 1] +top[j] * bottom[j + k] * top[j + k + 1] * bottom[j + i])
			}
			sort.Ints(tmp)
			dp[i][j] = tmp[0]
		}
	}
	fmt.Println(dp[n-1][0])
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

C++: #include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <set>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int,int> P;
typedef std::pair<int,P> State;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1}, dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

struct Deck{
    int first, last;
};

Deck ds[100];
// dp[i][j][k] := 位置iからj個とk個の山に分ける時の最小値
int dp[100][101][101];

int rec(int pos, int a, int b){
    if(dp[pos][a][b] != -1){
        return dp[pos][a][b];
    }

    if(a == 0 || b == 0){
        return 0;
    }

    int res = ds[pos].first * ds[pos+a-1].last * ds[pos+a].first * ds[pos+a+b-1].last;
    // printf("%d, %d, %d: %d\n", pos, a, b, res);
    if(a == 1 && b == 1){
        return res;
    }

    int min_a = rec(pos, 1, a-1);
    FOR(i, 2, a){
        min_a = std::min(rec(pos, i, a-i), min_a);
    }

    int min_b = rec(pos+a, 1, b-1);
    FOR(i, 2, b){
        min_b = std::min(rec(pos+a, i, b-i), min_b);
    }

    res += min_a + min_b;
    return dp[pos][a][b] = res;
}

int main(){
    int N;
    std::cin >> N;
    
    REP(i, N){
        std::cin >> ds[i].first >> ds[i].last;
    }
    std::fill(dp[0][0], dp[0][0]+100*101*101, -1);
    
    int res = rec(0, 1, N-1);
    FOR(i, 2, N){
        res = std::min(rec(0, i, N-i), res);
    }

    std::cout << res << std::endl;
}

C++: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()

typedef pair<int,int> pii;
int const INF = 1<<30;

int main() {
  int n;
  cin >> n;
  vector<int> v1(n),v2(n);
  REP(i,n) {
    cin >> v1[i] >> v2[i];
  }
  int ans = 0;
  while(v1.size()>1) {
    pii t1(INF,0),t2(INF,0),b1(INF,0),b2(INF,0);
    REP(i,n) {
      if (t1>pii(v1[i],i)) {
        t2 = t1;
        t1 = pii(v1[i],i);
      }
      if (b1>pii(v2[i],i)) {
        b2 = b1;
        b1 = pii(v2[i],i);
      }
    }
    int ue,shita;
    if (t1.second == b1.second) {
      if (t2.first < b2.first) {
        ue = t2.second;
        shita = b1.second;
      } else {
        ue = t1.second;
        shita = b2.second;
      }
    } else {
      ue = t1.second;
      shita = t2.second;
    }
    // cout << ue << " " << shita<< endl;
    ans += v1[ue]*v2[ue]*v1[shita]*v2[shita];
    v1.push_back(v1[ue]);
    v2.push_back(v2[shita]);
    v1.erase(v1.begin()+ue);
    v1.erase(v1.begin()+shita);
    v2.erase(v2.begin()+ue);
    v2.erase(v2.begin()+shita);
  }
  cout << ans << endl;
}

C++: #include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EACH(t,i,c) for(t::iterator i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
const double EPS = 1e-10;
const double PI  = acos(-1.0);

int dp[101][101];
int a[101],b[101];

const int MAX=INT_MAX/100;
int dfs(int l,int r){
	if(dp[l][r]!=MAX){
		return dp[l][r];
	}
	if(r-l==1){
		return dp[l][r]=min(dp[l][r],a[l]*b[l]*a[r]*b[r]);
	}else if(r==l){
		return dp[l][r]=0;
	}
	int best=MAX;
	FOR(i,l,r){
		int cost=a[l]*b[i]*a[i+1]*b[r];
		best=min(best,dfs(l,i)+dfs(i+1,r)+cost);
	}
	return dp[l][r]=min(dp[l][r],best);
}

int main(){
	int n;
	while(cin>>n,n){
		REP(i,n+1)REP(j,n+1){
			dp[i][j]=MAX;
		}

		REP(i,n){
			cin>>a[i]>>b[i];
		}

		cout<<dfs(0,n-1)<<endl;
	}
}

C++: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef complex<double> P;
static const double EPS = 1e-8;

#define FOR(i,k,n) for (int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
int dfs(int sum,vector<PII> yama){
  if(yama.size()==1) return sum;
  int MAX=-1e8;
  int ret = 1e9;
  REP(i,yama.size()-1){
    MAX = max(yama[i+1].first+yama[i].second-yama[i].first-yama[i+1].second,MAX);
  }
  REP(i,yama.size()-1){
    if(yama[i+1].first+yama[i].second-yama[i].first-yama[i+1].second==MAX){
      vector<PII> tmp=yama;
      int a=yama[i].first,b=yama[i].second,c=yama[i+1].first,d=yama[i+1].second;
      tmp.erase(tmp.begin()+i);
      tmp.erase(tmp.begin()+i);
      tmp.insert(tmp.begin()+i,PII(a,d));
      ret = min(ret,dfs(sum+a*b*c*d,tmp));
    }
  }
  return ret;
}
int main(void){
  int n;
  cin>>n;
  vector<PII> yama(n);
  REP(i,n){
    int a,b;
    cin>>a>>b;
    yama[i] = PII(a,b);
  }
  cout<<dfs(0,yama)<<endl;
  return 0;
}

C++: #include<stdio.h>
#include<algorithm>
using namespace std;
long long int dp[100][100];
long long int f[100];
long long int e[100];
long long int solve(long long int a,long long int b){
	long long int ret=(1LL<<31)-1;
	if(a==b)return 0;
	if(dp[a][b])return dp[a][b];
	for(long long int i=a;i<b;i++)ret=min(ret,solve(a,i)+solve(i+1,b)+f[a]*e[i]*f[i+1]*e[b]);
	return dp[a][b]=ret;
}
int main(){
	long long int n;
	scanf("%lld",&n);
	for(long long int i=0;i<n;i++)scanf("%lld%lld",f+i,e+i);
	printf("%lld\n",solve(0,n-1));
}