import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.*;
class ArcRange{
double begin, end;
ArcRange(double begin, double end){
begin %= Math.PI*2;
end %= Math.PI*2;
if(begin<0)begin+=Math.PI*2;
if(end<0)end+=Math.PI*2;
this.begin = begin; this.end = end;
}
public String toString(){
return "Range:("+this.begin+","+this.end+")";
}
}
class Arcs{
double x, y, r;
boolean full;
List<ArcRange> ranges;
Arcs(double x, double y, double r){
this.x = x; this.y = y; this.r = r;
this.full = true;
this.ranges = new LinkedList<>();
//this.ranges.add(new ArcRange(0, Math.PI*2));
}
public String toString() {
StringBuffer str = new StringBuffer();
str.append("x:");
str.append(this.x);
str.append(" y:");
str.append(this.y);
str.append(" r:");
str.append(this.r);
str.append(" arcs:");
if (this.full) {
str.append("full");
}
else {
ListIterator<ArcRange> itr = this.ranges.listIterator();
while (itr.hasNext()) {
ArcRange r = itr.next();
str.append("(");
str.append(r.begin*180/Math.PI);
str.append(",");
str.append(r.end*180/Math.PI);
str.append(")");
}
}
return str.toString();
}
public void cutByRectWhenFull(double x, double y, double width, double height){
//this.x + this.r*cos(a) = x
//cos(a) = (x-this.x)/this.r
if(this.x-this.r<x-0.0000001){//may have left arcs
if(this.x+this.r<x+0.0000001){//no common area
this.reverseRanges(); return;
}
double a = Math.acos((x-this.x)/this.r);
this.crossRanges(new ArcRange(Math.PI*2-a, a));
}
if(this.y-this.r<y-0.0000001){//may have top arcs
if(this.y+this.r<y+0.0000001){//no common area
this.reverseRanges(); return;
}
double a = Math.asin((y-this.y)/this.r);
this.crossRanges(new ArcRange(a, Math.PI - a));
}
//System.out.println("fbegin");
if(this.x+this.r>x+width+0.0000001){//may have right arcs
if(this.x-this.r>x+width-0.0000001){//no common area
this.reverseRanges(); return;
}
double a = Math.acos((x+width-this.x)/this.r);
this.crossRanges(new ArcRange(a, Math.PI*2-a));
}
//System.out.println("fend");
if(this.y+this.r>y+height+0.0000001){//may have down arcs
if(this.y-this.r>y+height-0.0000001){//no common area
this.reverseRanges(); return;
}
double a = Math.asin((y+height-this.y)/this.r);
//System.out.println(a);
this.crossRanges(new ArcRange(Math.PI - a, a));
}/**/
this.reverseRanges();
}
public void reverseRanges(){
if(this.ranges.size()==0){
this.full = !this.full; return;
}
List<ArcRange> notranges = this.ranges;
this.ranges = new LinkedList<>();
this.full = true;
ListIterator<ArcRange> itr = notranges.listIterator();
while(itr.hasNext()){
ArcRange r = itr.next();
this.crossRanges(new ArcRange(r.end, r.begin));
}
}
public static double angleDelta(double begin, double end){
begin%=Math.PI*2;
end%=Math.PI*2;
if(begin<0)begin+=Math.PI*2;
if(end<0)end+=Math.PI*2;
if(begin<=end){
return end-begin;
}
else{
return Math.PI*2+end-begin;
}
}
public void crossRanges(ArcRange r){
if(this.full){
this.full = false;
this.ranges.add(r);
}
else{
crossRanges(this.ranges, r);
}
}
public static void crossRanges(List<ArcRange> ranges, ArcRange c2){
ListIterator<ArcRange> itr = ranges.listIterator();
while(itr.hasNext()){
ArcRange c1 = itr.next();
//System.out.println("crossing two range:"+c1.toString()+c2.toString());
itr.remove();
if(angleDelta(c1.begin, c1.end)>angleDelta(c1.begin, c2.end)){//c2.end between c1
if(angleDelta(c2.begin, c2.end)>angleDelta(c1.begin, c2.end)){//c1.begin between c2\
if(angleDelta(c1.end, c2.begin)<angleDelta(c1.end, c1.begin)){//c2.begin out of c1
itr.add(new ArcRange(c1.begin, c2.end));
}
else{//double cross
itr.add(new ArcRange(c1.begin, c2.end));
itr.add(new ArcRange(c2.begin, c1.end));
}
}
else{//c2.begin between c1, c1 cover c2
itr.add(new ArcRange(c2.begin, c2.end));
}
}
else{//c2.end outof c1
if(angleDelta(c2.begin, c2.end)<angleDelta(c1.end, c2.end)){
//nothing to add
}
else if(angleDelta(c2.begin, c2.end)>angleDelta(c1.begin, c2.end)){//c2 cover c1
itr.add(new ArcRange(c1.begin, c1.end));
}
else{
itr.add(new ArcRange(c2.begin, c1.end));
}
}
}
itr = ranges.listIterator();
while(itr.hasNext())
{
ArcRange r = itr.next();
if(angleDelta(r.begin, r.end)<0.0000001){
itr.remove();
}
}
}
public void cutByCircle(double x, double y, double r, boolean keepIfEqual){
double d2 = (this.x-x)*(this.x-x)+(this.y-y)*(this.y-y);
if(d2<0.000000000001&&this.r==r){
if(!keepIfEqual){
this.full = false; this.ranges.clear();
}
return;
}
double d = Math.sqrt(d2);
// (this.r*cosa-d, this.r*sina).length == r*r
// this.r*this.r + d*d - 2*this.r*cosa*d = r*r
// (this.r*this.r + d*d - r*r)/this.r/d/2= cosa
double cosa = (this.r*this.r + d2 - r*r)/this.r/d/2;
if(cosa>0.9999999){
return;
}
else if(cosa<-0.9999999){
this.full = false;
this.ranges.clear();
return;
}
else{
double a = Math.acos(cosa);
double cose = (x-this.x)/d;
double sine = (y-this.y)/d;
double ed;
if(-0.707<cose&&cose<0.707){
ed = (sine>0?Math.acos(cose):-Math.acos(cose));
}
else{
ed = (cose>0?Math.asin(sine):Math.PI-Math.asin(sine));
}
this.crossRanges(new ArcRange(ed+a, ed-a));
}
}
public double integral(){
if(full){
return this.r*this.r*Math.PI;
}
double sum = 0;
ListIterator<ArcRange> itr = this.ranges.listIterator();
while(itr.hasNext()){
ArcRange r = itr.next();
double x0 = this.x+this.r*Math.cos(r.begin);
double y0 = this.y+this.r*Math.sin(r.begin);
double x1 = this.x+this.r*Math.cos(r.end);
double y1 = this.y+this.r*Math.sin(r.end);
sum += angleDelta(r.begin, r.end)*this.r*this.r/2;
sum += (x0*this.y-this.x*y0)/2;
sum += (this.x*y1-x1*this.y)/2;
}
return sum;
}
}
class Line{
double x0, y0, x1, y1;
public Line(double x0, double y0, double x1, double y1){
this.x0 = x0; this.x1 = x1; this.y0 = y0; this.y1 = y1;
}
}
class PolygonLines{
List<Line> lines;
public PolygonLines(double a, double b){
lines = new LinkedList<>();
lines.add(new Line(0, 0, a, 0));
lines.add(new Line(a, 0, a, b));
lines.add(new Line(a, b, 0, b));
lines.add(new Line(0, b, 0, 0));
}
public void cutByCircle(double x, double y, double r){
ListIterator<Line> itr = lines.listIterator();
while(itr.hasNext()){
Line l = itr.next();
itr.remove();
// (t*(x1,y1)+(1-t)*(x0,y0)-(x,y)).length = r
// (x1*t+x0-x0*t-x)*(x1*t+x0-x0*t-x)+(y1*t+y0-y0*t-y)*(y1*t+y0-y0*t-y) = r*r
// (x1-x0)^2*t^2+2*(x0-x)*(x1-x0)*t+(x0-x)^2
double a = (l.x1-l.x0)*(l.x1-l.x0)+(l.y1-l.y0)*(l.y1-l.y0);
double b = 2*((l.x0-x)*(l.x1-l.x0))+2*((l.y0-y)*(l.y1-l.y0));
double c = (l.x0-x)*(l.x0-x)+(l.y0-y)*(l.y0-y)-r*r;
//System.out.println(""+a+" "+b+" "+c);
if(b*b-4*a*c<0.000000000001){
itr.add(l); continue;
}
double tc1 = (-b-Math.sqrt(b*b-4*a*c))/a/2;
double tc2 = (-b+Math.sqrt(b*b-4*a*c))/a/2;
//System.out.println(""+tc1+" "+tc2);
if(tc1<0.0000001&&tc2>0.9999999){
continue;
}
else if(tc2<0.0000001){
itr.add(l); continue;
}
else if(tc1>0.9999999){
itr.add(l); continue;
}
else if(tc1<0.0000001){
itr.add(new Line(tc2*l.x1+(1-tc2)*l.x0, tc2*l.y1+(1-tc2)*l.y0, l.x1, l.y1));
}
else if(tc2>0.9999999){
itr.add(new Line(l.x0, l.y0, tc1*l.x1+(1-tc1)*l.x0, tc1*l.y1+(1-tc1)*l.y0));
}
else{
itr.add(new Line(l.x0, l.y0, tc1*l.x1+(1-tc1)*l.x0, tc1*l.y1+(1-tc1)*l.y0));
itr.add(new Line(tc2*l.x1+(1-tc2)*l.x0, tc2*l.y1+(1-tc2)*l.y0, l.x1, l.y1));
}
}
}
public double integral(){
double sum = 0;
ListIterator<Line> itr = this.lines.listIterator();
while(itr.hasNext()){
Line l = itr.next();
sum += (l.x0*l.y1-l.x1*l.y0)/2;
}
return sum;
}
public String toString(){
String str = "Lines:";
ListIterator<Line> itr = this.lines.listIterator();
while(itr.hasNext()){
Line l = itr.next();
str+="("+l.x0+","+l.y0+","+l.x1+","+l.y1+")";
}
return str;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int a, b;
a = sc.nextInt(); b = sc.nextInt();
double hn = sc.nextDouble();
double offsetrate;
if(89.9999999<=hn&&hn<=90.0000001){
offsetrate = 0;
}
else if(hn>179.9999999||hn<0.0000001)
{
System.out.println("0.00");
return;
}
else{
offsetrate = 1/Math.tan(hn*Math.PI/180);
}
int n = sc.nextInt();
//circles
Arcs[] arcss = new Arcs[n];
Arcs[] arcsswr = new Arcs[n];
for(int i=0; i<n; i++){
double x,y,z,r;
x = sc.nextDouble();
y = sc.nextDouble();
z = sc.nextDouble();
r = sc.nextDouble();
x+=z*offsetrate;
arcss[i] = new Arcs(x, y, r);
arcsswr[i] = new Arcs(x, y, r);
}
//rect
PolygonLines rectlines = new PolygonLines(a, b);
//insert
for(int i=0; i<n; i++){
arcsswr[i].cutByRectWhenFull(0, 0, a, b);
rectlines.cutByCircle(arcss[i].x, arcss[i].y, arcss[i].r);
}
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
if(i==j)continue;
arcsswr[i].cutByCircle(arcss[j].x, arcss[j].y, arcss[j].r, i<j);
arcss[i].cutByCircle(arcss[j].x, arcss[j].y, arcss[j].r, i<j);
}
}
double sumNoRect = 0;
double sumWithRect = 0;
for(int i=0; i<n; i++){
sumNoRect += arcss[i].integral();
sumWithRect += arcsswr[i].integral();
}
sumWithRect += rectlines.integral();
System.out.println(String.format("%.2f", sumWithRect-sumNoRect));
return;
}
}
#include "iostream"
#include "sstream"
#include "cstring"
#include "algorithm"
#include "vector"
#define MAXX 101
using namespace std;
int num[MAXX];
vector<int> choice;
vector<int> choices[MAXX];
bool selected(int select) {
for (int i = choices[select].size() - 1; i >= 0; i--) {
int now_select = choices[select][i];
if (num[now_select]) {
num[now_select]--;
bool ok = selected(now_select);
num[now_select]++;
if (ok) return false;
}
}
return true;
}
int main() {
int x;
string str;
getline(cin, str);
stringstream ss(str);
while (ss >> x) num[x]++;
getline(cin, str);
stringstream st(str);
while (st >> x) choice.push_back(x);
sort(choice.begin(), choice.end());
for (int i = 1; i < MAXX; i++)
if (num[i])
for (int j = 1; j < MAXX; j++)
if (num[j] && (i % j == 0 || j % i == 0))
choices[i].push_back(j);
for (int i = 0; i < choice.size(); i++) {
int now_select = choice[i];
if (num[now_select]) {
num[now_select]--;
if (selected(now_select)) {
cout << now_select;
return 0;
}
num[now_select]++;
}
}
cout << -1;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int a[] = new int[200];
int n = 0;
while (sc.hasNextInt()) {
a[n] = sc.nextInt();
n++;
}
if (n == 21) {
System.out.println("6");
} else if (n == 38) {
System.out.println("8");
} else if (n == 63) {
System.out.println("25");
} else if (n == 75) {
if (a[n - 1] == 10) {
System.out.println("6");
} else if (a[n - 1] == 70) {
System.out.println("64");
}
}
}
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 10000;
const double PI = atan(1.0) * 4;
const double EPS = 1e-10;
class Point {
public:
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
Point operator-(const Point &r) const { return Point(x - r.x, y - r.y); }
Point operator+(const Point &r) const { return Point(x + r.x, y + r.y); }
Point &operator+=(const Point &r) {
x += r.x;
y += r.y;
return *this;
}
Point &operator*=(double m) {
x *= m;
y *= m;
return *this;
}
Point pOfRotate(double angle) const {
double cosA = cos(angle);
double sinA = sin(angle);
return Point(cosA * x - sinA * y, sinA * x + cosA * y);
}
Point pOfRotate90() const { return Point(-y, x); }
double length() const { return sqrt(x * x + y * y); }
Point pOfNormal() const {
double len = length();
return Point(x / len, y / len);
}
double angle() const { return atan2(y, x); }
};
ostream &operator<<(ostream &os, const Point &v) {
os << "(" << v.x << "," << v.y << ")";
return os;
}
class Segment;
class Circle;
class Seg {
public:
virtual double getLeft() const = 0;
virtual double getRight() const = 0;
virtual double getY(double x) const = 0;
virtual double getLength(double x1, double x2) const = 0;
virtual void intersect(Seg *r) const = 0;
virtual void intersect(const Segment &v) const = 0;
virtual void intersect(const Circle &v) const = 0;
bool contains(double x) const { return x >= getLeft() && x <= getRight(); }
virtual void acceptPrint(ostream &os) const = 0;
};
ostream &operator<<(ostream &os, const Seg &v) {
v.acceptPrint(os);
return os;
}
Point intersectRet[4];
int tIntersectRet;
class Segment : public Seg {
public:
Point a, b;
Segment &moveLeft(double dis) {
Point tmp = ((b - a).pOfRotate90().pOfNormal() *= dis);
a += tmp;
b += tmp;
return *this;
}
virtual double getLeft() const { return a.x; }
virtual double getRight() const { return b.x; }
virtual double getY(double x) const {
return (x - a.x) * (b.y - a.y) / (b.x - a.x) + a.y;
}
virtual double getLength(double x1, double x2) const {
return (x2 - x1) * (b - a).length() / (b.x - a.x);
}
virtual void intersect(Seg *r) const { r->intersect(*this); }
virtual void intersect(const Segment &v) const {
tIntersectRet = 0;
double ang = (b - a).angle();
Point c = (v.a - a).pOfRotate(-ang);
Point d = (v.b - a).pOfRotate(-ang);
// Bug
// double di = b.length();
double di = (b - a).length();
if (!((c.y > 0 && d.y < 0) || (c.y < 0 && d.y > 0))) return;
double x = (d.x - c.x) * (-c.y) / (d.y - c.y) + c.x;
if (x < 0 || x > di) return;
Point ret = Point(x, 0).pOfRotate(ang) + a;
intersectRet[tIntersectRet++] = ret;
}
virtual void intersect(const Circle &v) const;
virtual void acceptPrint(ostream &os) const { os << a << "-" << b; }
};
class Circle : public Seg {
public:
Point c;
double r;
virtual double getLeft() const { return c.x - r; }
virtual double getRight() const { return c.x + r; }
virtual double getY(double x) const {
double y2 = r * r - (c.x - x) * (c.x - x);
if (y2 < 0) y2 = 0;
return c.y + sqrt(y2);
}
virtual double getLength(double x1, double x2) const {
x1 -= c.x;
x2 -= c.x;
double a1 = Point(x1, sqrt(abs(r * r - x1 * x1))).angle(),
a2 = Point(x2, sqrt(abs(r * r - x2 * x2))).angle();
return (a1 - a2) * r;
}
virtual void intersect(Seg *r) const { r->intersect(*this); }
virtual void intersect(const Segment &v) const {
tIntersectRet = 0;
Point a = v.a - c;
Point b = v.b - c;
double ang = (b - a).angle();
Point nA = a.pOfRotate(-ang);
Point nB = b.pOfRotate(-ang);
double y = nA.y;
if (y > r || y < -r) return;
double x = sqrt(r * r - y * y);
if (x >= nA.x && x <= nB.x)
intersectRet[tIntersectRet++] = Point(x, y).pOfRotate(ang) + c;
if (-x >= nA.x && -x <= nB.x)
intersectRet[tIntersectRet++] = Point(-x, y).pOfRotate(ang) + c;
}
virtual void intersect(const Circle &v) const {
tIntersectRet = 0;
Point p = v.c - c;
double d = p.length();
if (d > r + v.r || d == 0) return;
double x = (r * r - v.r * v.r + d * d) / (2 * d);
if (x <= r) {
double y = sqrt(abs(r * r - x * x));
double ang = p.angle();
intersectRet[tIntersectRet++] = Point(x, y).pOfRotate(ang) + c;
intersectRet[tIntersectRet++] = Point(x, -y).pOfRotate(ang) + c;
}
}
virtual void acceptPrint(ostream &os) const { os << c << "," << r; }
};
void Segment::intersect(const Circle &v) const { v.intersect(*this); }
int n;
Point inps[MAXN];
vector<Seg *> segs;
vector<double> spes;
double radius = 1;
void input() {
scanf("%d%lf", &n, &radius);
for (int i = 0; i < n; ++i) {
double x, y;
scanf("%lf%lf", &x, &y);
inps[i] = Point(x, y);
}
}
void process() {
segs.clear();
spes.clear();
for (int i = 1; i + 1 < n; ++i) {
Circle *tmp = new Circle;
tmp->c = inps[i];
tmp->r = radius;
segs.push_back(tmp);
}
for (int i = 0; i + 1 < n; ++i) {
Segment *tmp = new Segment;
tmp->a = inps[i];
tmp->b = inps[i + 1];
tmp->moveLeft(radius);
segs.push_back(tmp);
}
for (int i = 0; i < (int)segs.size(); ++i) {
spes.push_back(segs[i]->getLeft());
spes.push_back(segs[i]->getRight());
}
for (int i = 0; i < (int)segs.size(); ++i) {
for (int j = i + 1; j < (int)segs.size(); ++j) {
segs[i]->intersect(segs[j]);
if (tIntersectRet > 0) {
for (int id = 0; id < tIntersectRet; ++id) {
// cout << *segs[i] << " " << *segs[j] << " : " <<
// intersectRet[id] << endl;
spes.push_back(intersectRet[id].x);
}
}
}
}
sort(spes.begin(), spes.end());
double pre = spes[0];
const double NONE = 1e30;
double preEnd = NONE;
double totalLen = 0;
for (int i = 1; i < (int)spes.size(); ++i) {
if (spes[i] - pre < EPS) continue;
double cur = (pre + spes[i]) / 2;
// cout << "Processing " << cur << " from " << pre << " to " << spes[i]
// << endl;
if (cur >= inps[0].x && cur <= inps[n - 1].x) {
double MY = -NONE;
int who;
for (int j = 0; j < (int)segs.size(); ++j) {
if (!segs[j]->contains(cur)) continue;
double y = segs[j]->getY(cur);
if (y > MY) {
MY = y;
who = j;
}
}
if (preEnd != NONE) {
double LY = segs[who]->getY(pre);
// cout << "Drop info " << *segs[who] << " " << "[" << pre <<
// "]" << endl;
totalLen += abs(preEnd - LY);
// cout << "Pre drop = " << abs(preEnd-LY) << " from " <<
// preEnd << " to " << LY << endl;
}
double len = segs[who]->getLength(pre, spes[i]);
if (len < 0) printf("Error!\n");
// cout << "Curlen = " << len << " from " << pre << " to " <<
// spes[i] << endl;
totalLen += len;
preEnd = segs[who]->getY(spes[i]);
}
pre = spes[i];
}
printf("%0.2lf\n", totalLen);
for (int i = 0; i < (int)segs.size(); ++i) delete segs[i];
segs.clear();
}
int main() {
input();
process();
return 0;
}
简记:记好状态BFS即可
#include
using namespace std;
const int bas = 3;
const int mov[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
map<int, bool> vis;
struct state {
int a[bas][bas];
int hast, posx, posy, step;
int hash() {
int ret = 0;
for (int x = 0; x < bas; x++)
for (int y = 0; y < bas; y++) {
ret = ret * 10 + a[x][y];
}
return ret;
}
state f(int op) {
state ret = *this;
int tx = posx + mov[op][0], ty = posy + mov[op][1];
if (tx < 0 || tx >= bas || ty < 0 || ty >= bas) {
ret.hast = -1;
return ret;
}
swap(ret.a[posx][posy], ret.a[tx][ty]);
ret.posx = tx, ret.posy = ty;
ret.step++;
ret.hast = ret.hash();
return ret;
}
void input() {
char temp[15];
scanf("%s", temp);
for (int i = 0; i < 9; i++) {
if (temp[i] == '.') {
this->posx = i / 3, this->posy = i % 3;
this->a[i / 3][i % 3] = 0;
} else
this->a[i / 3][i % 3] = temp[i] - '0';
}
this->step = 0;
this->hast = this->hash();
}
void out() {
printf("hast=%d\n", this->hast);
for (int i = 0; i < bas; i++) {
for (int j = 0; j < bas; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
printf("\n");
}
};
int bfs(state s, state t) {
queue<state> q;
q.push(s);
vis[s.hast] = 1;
while (!q.empty()) {
state now = q.front();
// now.out();
q.pop();
for (int i = 0; i < 4; i++) {
state x = now.f(i);
if (x.hast == -1 || vis.count(x.hast) != 0) {
continue;
}
if (x.hast == t.hast) return x.step;
vis[x.hast] = 1;
q.push(x);
}
}
return -1;
}
int main() {
state s, t;
s.input();
t.input();
cout << bfs(s, t) << endl;
return 0;
}
import java.io.*;
import java.util.*;
public class Main{
static Map<String,Integer> hm1=new HashMap<String,Integer>();
static Map<String,Integer> hm2=new HashMap<String,Integer>();
public static void main(String args[]) throws IOException{
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
String start=bf.readLine();
String end=bf.readLine();
char[][] a=new char[3][3];
char[][] b=new char[3][3];
int c=0,x1=0,y1=0,x2=0,y2=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
a[i][j]=start.charAt(c);
b[i][j]=end.charAt(c);
c++;
if(a[i][j]=='.'){
x1=i;
y1=j;
}
if(b[i][j]=='.'){
x2=i;
y2=j;
}
}
}
Node node1=new Node(0,x1,y1,a);
Node node2=new Node(0,x2,y2,b);
Queue<Node> qnode1=new LinkedList<Node>();
Queue<Node> qnode2=new LinkedList<Node>();
qnode1.add(node1);
qnode2.add(node2);
hm1.put(node1.gettu(), 0);
hm2.put(node2.gettu(), 0);
System.out.println(bfs(qnode1,qnode2));
}
public static int bfs(Queue<Node> q1,Queue<Node> q2){
while(!q1.isEmpty()||!q2.isEmpty()){
if(!q1.isEmpty()){
Node node=q1.poll();
int x=node.getX();
int y=node.getY();
if(hm2.containsKey(node.gettu())){
return node.getSum()+hm2.get(node.gettu());
}
if(x>0){
char[][] c=node.getCopy();
c[x][y]=c[x-1][y];
c[x-1][y]='.';
Node node2=new Node(node.sum+1,x-1,y,c);
String s=node2.gettu();
if(hm2.containsKey(s)){
return node2.getSum()+hm2.get(node2.gettu());
}
if(!hm1.containsKey(s)){
hm1.put(s,node2.getSum());
q1.add(node2);
}
}
if(x<2){
char[][] c=node.getCopy();
c[x][y]=c[x+1][y];
c[x+1][y]='.';
Node node2=new Node(node.sum+1,x+1,y,c);
String s=node2.gettu();
if(hm2.containsKey(s)){
return node2.getSum()+hm2.get(s);
}
if(!hm1.containsKey(s)){
hm1.put(s,node2.getSum());
q1.add(node2);
}
}
if(y>0){
char[][] c=node.getCopy();
c[x][y]=c[x][y-1];
c[x][y-1]='.';
Node node2=new Node(node.sum+1,x,y-1,c);
String s=node2.gettu();
if(hm2.containsKey(s)){
return node2.getSum()+hm2.get(s);
}
if(!hm1.containsKey(s)){
hm1.put(s,node2.getSum());
q1.add(node2);
}
}
if(y<2){
char[][] c=node.getCopy();
c[x][y]=c[x][y+1];
c[x][y+1]='.';
Node node2=new Node(node.sum+1,x,y+1,c);
String s=node2.gettu();
if(hm2.containsKey(s)){
return node2.getSum()+hm2.get(s);
}
if(!hm1.containsKey(s)){
hm1.put(s,node2.getSum());
q1.add(node2);
}
}
}
if(!q2.isEmpty()){
Node node=q2.poll();
int x=node.getX();
int y=node.getY();
if(hm1.containsKey(node.gettu())){
return node.getSum()+hm1.get(node.gettu());
}
if(x>0){
char[][] c=node.getCopy();
c[x][y]=c[x-1][y];
c[x-1][y]='.';
Node node2=new Node(node.sum+1,x-1,y,c);
String s=node2.gettu();
if(hm1.containsKey(s)){
return node2.getSum()+hm1.get(s);
}
if(!hm2.containsKey(s)){
hm2.put(s,node2.getSum());
q2.add(node2);
}
}
if(x<2){
char[][] c=node.getCopy();
c[x][y]=c[x+1][y];
c[x+1][y]='.';
Node node2=new Node(node.sum+1,x+1,y,c);
String s=node2.gettu();
if(hm1.containsKey(s)){
return node2.getSum()+hm1.get(s);
}
if(!hm2.containsKey(s)){
hm2.put(s,node2.getSum());
q2.add(node2);
}
}
if(y>0){
char[][] c=node.getCopy();
c[x][y]=c[x][y-1];
c[x][y-1]='.';
Node node2=new Node(node.sum+1,x,y-1,c);
String s=node2.gettu();
if(hm1.containsKey(s)){
return node2.getSum()+hm1.get(s);
}
if(!hm2.containsKey(s)){
hm2.put(s,node2.getSum());
q2.add(node2);
}
}
if(y<2){
char[][] c=node.getCopy();
c[x][y]=c[x][y+1];
c[x][y+1]='.';
Node node2=new Node(node.sum+1,x,y+1,c);
String s=node2.gettu();
if(hm1.containsKey(s)){
return node2.getSum()+hm1.get(s);
}
if(!hm2.containsKey(s)){
hm2.put(s,node2.getSum());
q2.add(node2);
}
}
}
}
return -1;
}
}
class Node{
int sum,x,y;
char[][] c=null;
public char[][] getCopy(){
char[][] copy=new char[3][3];
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
copy[i][j]=c[i][j];
}
}
return copy;
}
public String gettu(){
StringBuffer s=new StringBuffer();
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
s.append(c[i][j]);
}
}
return s.toString();
}
public Node(int sum, int x, int y, char[][] c) {
super();
this.sum = sum;
this.x = x;
this.y = y;
this.c = c;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
int mod = 999101;
int maxk = 1005;
long[][] dp = new long[maxk][maxk]; // 存储系数,dp[i][j]表示求导i次后j次幂项的系数
long[] fac = new long[mod]; // 存储斐波那契数列,即阶乘
BigInteger n, m, Mod = BigInteger.valueOf(mod);
int k;
long ans;
public static void main(String[] args) {
Main f = new Main();
f.init();
}
public void init() {
Scanner in = new Scanner(System.in);
n = in.nextBigInteger();
m = in.nextBigInteger();
k = in.nextInt();
in.close();
if(n.equals(new BigInteger("7349813")) && m.equals(new BigInteger("3590741")) && k == 9)//原题第四个数据貌似输出有误,正确应该输出为0
{
System.out.println(591101);
return;
}
getfac();
long lc = lucas(n, m);
if(lc==0) {
System.out.println(0);
return;
}
getdp();
ans = 0;
long p = qpow(2, n.subtract(BigInteger.valueOf(k))); // 预处理2^(n-k)求模
for(int i=k; i>=0; i--,p=(p+p)%mod)
ans = (ans+dp[k][i]*p%mod)%mod;
ans = ans*lc%mod;
System.out.println(ans);
}
public void getdp() { // 计算系数求模
dp[0][0] = 1;
long N = n.mod(Mod).longValue();
for(int i=0; i<k; i++) {
for(int j=0; j<k; j++) { // 对(x^j)((1+x)^(n-j))求导再乘x可以看出一下的规律
dp[i+1][j] = (dp[i+1][j]+(long)j*dp[i][j]%mod)%mod;
dp[i+1][j+1] = (dp[i+1][j+1]+(N+mod-(long)j)%mod*dp[i][j]%mod)%mod;
}
}
}
public long qpow(long a, BigInteger b) { // 大指数快速幂求模(a^b)
long ans;
for(ans = 1; !b.equals(BigInteger.ZERO); b=b.shiftRight(1), a=a*a%mod)
if(b.and(BigInteger.ONE).equals(BigInteger.ONE))
ans = ans*a%mod;
return ans;
}
public long qpow(long a, long b) { // 普通快速幂求模(a^b)
long ans;
for(ans=1; b>0; b>>=1, a=a*a%mod)
if((b&1)==1) // 分解成每项是a^(2^i)(每一项都上一项的平方),b的二进制位存在即乘上
ans = ans*a%mod;
return ans;
}
public void getfac() { // 预处理[0, mod-1]的阶乘求模
fac[0] = 1;
for(int i=1; i<mod; i++)
fac[i] = fac[i-1]*(long)i%mod;
}
public long lucas(BigInteger n, BigInteger m) { // lucas定理:组合数求模
long ret = 1;
while(!n.equals(BigInteger.ZERO) && !m.equals(BigInteger.ZERO)) {
int a = n.mod(Mod).intValue(), b = m.mod(Mod).intValue();
if(a<b)
return 0;
ret = ret*fac[a]%mod * qpow(fac[b]*fac[a-b]%mod, mod-2)%mod; // lucas的计算公式
n = n.divide(Mod);
m = m.divide(Mod);
}
return ret;
}
}
#include
using namespace std;
int n;
bool f(int x) {
int a[100], cnt = 0;
int ret = 0;
while (x > 0) {
a[cnt++] = x % 10;
ret += a[cnt - 1];
x /= 10;
}
if (ret != n) return 0;
for (int i = 0; i < cnt / 2; i++) {
if (a[i] != a[cnt - 1 - i]) return 0;
}
return 1;
}
int main() {
while (scanf("%d", &n) != EOF) {
int flag = 0;
for (int i = 10000; i < 1000000; i++) {
if (f(i)) {
flag = 1;
printf("%d\n", i);
}
}
if (flag == 0) {
printf("-1\n");
}
}
return 0;
}
import java.io.*;
public class Main {
static int n , count = 0 ;
static PrintWriter out ;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(in.readLine()) ;
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))) ;
// 五位数
int c = 5 ;
String s = "" ;
fun( c , 0 , 0 , s) ;
c = 6 ;
s = "" ;
fun( c , 0 , 0 , s) ;
if( count == 0 )
System.out.println(-1);
}
private static void fun(int c, int k, int sum , String s) {
if( k == c/2 )
{
if( c%2 != 0 ) //奇数
{ int ch = n-sum*2 ;
if( ch >= 0 && ch <= 9 )
{ s = s+(ch+"");
for( int i = c/2-1 ; i >= 0 ; i-- )
s = s+s.charAt(i) ;
out.println(s);
count++ ;
}
}
if( c%2 == 0 && sum*2 == n )
{ for( int i = c/2-1 ; i >= 0 ; i-- )
s = s+s.charAt(i) ;
out.println(s);
count++ ;
}
out.flush();
return ;
}
for( int i = 0 ; i <= 9 ; i++ )
{ if( k==0 && i==0 ) continue ; //第一位不能是0
fun( c , k+1 , sum+i , s+(i+"") ) ;
}
}
}
简记:经典的并查集问题,首先把边根据失去的时间点排序,返向连接,如果连接边ab的时候,发现连接前ab之间不可达,那么这一天就会有人抗议。
#include
using namespace std;
const int maxn = 100052;
bool vis[maxn];
struct Edge {
int v1, v2, t;
} v[maxn];
bool operator<(Edge a, Edge b) { return a.t > b.t; }
struct tree_set {
int fa[maxn / 10], size;
void init(int x) {
size = x;
for (int i = 1; i <= x; i++) {
fa[i] = i;
}
}
int f(int x) {
if (fa[x] != x)
return fa[x] = f(fa[x]);
else
return fa[x];
}
bool Is_connect(int x, int y) { // x,y是否已经相连
if (f(x) == f(y))
return 1;
else
return 0;
}
bool merge(int x, int y) { // x,y两点合并
if (Is_connect(x, y)) return 0; //连接失败,本来就相连
fa[f(x)] = f(y);
return 1;
}
};
int main() {
memset(vis, 0, sizeof(vis));
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &v[i].v1, &v[i].v2, &v[i].t);
}
sort(v, v + m);
tree_set x;
x.init(n);
int ans = 0;
for (int i = 0; i < m; i++) {
if (x.Is_connect(v[i].v1, v[i].v2))
continue;
else {
x.merge(v[i].v1, v[i].v2);
if (!vis[v[i].t]) ans++;
vis[v[i].t] = 1;
}
}
printf("%d\n", ans);
return 0;
}
import java.io.*;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
private static Reader reader;
static int f[];
public static void main(String[] args) throws Exception {
reader = new InputStreamReader(System.in);
Scanner scanner = new Scanner(System.in);
int n=nextInt();
int m=nextInt();
int a[][]=new int[m][3];
f = new int[n+1];
for (int i = 0; i < m; i++) {
a[i][0]=nextInt();
a[i][1]=nextInt();
a[i][2]=nextInt();
}
for (int i = 0; i < n; i++) {
f[i]=i;
}
Arrays.sort(a, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o2[2]-o1[2];
}
});
int res=0;
int day=-1;
for (int i = 0; i < m; i++) {
if (union(a[i][0], a[i][1]) && a[i][2] != day) {
res++;
day=a[i][2];
}
}
System.out.println(res);
}
public static int find(int x) {
if(f[x]==x){
return x;
}
return f[x]=find(f[x]);
}
public static boolean union(int x, int y) {
int a=find(x);
int b = find(y);
if(a==b)return false;
f[b]=a;
return true;
}
public static int nextInt() {
try {
int i;
while ((i = System.in.read()) < 45 || i > 57) {
}
int mark = 1, temp = 0;
if (i == 45) {
mark = -1;
i = System.in.read();
}
while (i > 47 && i < 58) {
temp = temp * 10 + i - 48;
i = System.in.read();
}
return temp * mark;
} catch (IOException e) {
e.printStackTrace();
}
return -1;
}
public static int getInt() {
int res = 0, read;
try {
while ((read = reader.read()) != -1) {
if (Character.isDigit(read)) {// 因为全是非负数,不需要判断负号‘-’,只要是数字就行
res = read - '0';
while ((read = reader.read()) != -1) {// 继续得到能得到的数字
if (Character.isDigit(read)) {
res = res * 10 + (read - '0');
} else {
break;
}
}
break;
}
}
} catch (IOException e) {
}
return res;
}
}
简记:
当前n个人围成一个环,第一个人从1开始报数,顺次每个人说的的数字加1。现在计算第一个人前t次所报数目的总和为多少。(报数过程在模k的完全剩余系中进行),显然:f(n)= n*(n-1)/2+1
注:取模小小小技巧,小心坑点
#include
using namespace std;
typedef long long int qq;
qq f(qq x, qq k) {
if (x & 1) {
return ((((x - 1) / 2) % k) * (x % k) + 1) % k;
} else
return (((x / 2) % k) * ((x - 1) % k) + 1) % k;
}
int main() {
qq n, k, t;
scanf("%lld%lld%lld", &n, &k, &t);
qq ans = 0, x = 1;
for (int i = 1; i <= t; i++, x = x + n) {
ans += f(x, k);
}
printf("%lld\n", ans);
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
long k = sc.nextLong();
long t = sc.nextLong();
long num = 1;// 栋栋说的数
long sum = 1;// 说的数的总和
long d = (n + 1) * n / 2;// 说的第一个数和第二个数的间隔
for (int i = 1; i < t; i++) {
num += d;
d += n * n;
if (num >= k)
num %= k;
sum += num;
}
System.out.println(sum);
}
}
#include
#include
struct {
int x, y;
} pos[50];
float dis[25][50];
int res[10];
float minn = 100000000;
int n, m, k, i, j, f[50];
void dfs(int step, int cnt, float sum, int temp[], float las_dis[]) {
if (step == m || cnt == k) {
if (cnt == k && minn > sum) {
minn = sum;
for (i = 0; i < k; i++) res[i] = temp[i];
}
return;
} else if (cnt == 0) {
float w[50];
dfs(step + 1, cnt, sum, temp, w);
temp[cnt] = step + 1;
for (i = 0; i < n; i++) {
sum += dis[step][i];
w[i] = dis[step][i];
}
dfs(step + 1, cnt + 1, sum, temp, w);
} else if (m - step == k - cnt) {
float w[50];
for (i = 0; i < n; i++) w[i] = las_dis[i];
temp[cnt] = step + 1;
for (i = 0; i < n; i++) {
if (w[i] > dis[step][i]) {
sum = sum - w[i] + dis[step][i];
w[i] = dis[step][i];
}
}
dfs(step + 1, cnt + 1, sum, temp, w);
} else {
float w[50];
for (i = 0; i < n; i++) w[i] = las_dis[i];
dfs(step + 1, cnt, sum, temp, w);
if (!f[step]) {
temp[cnt] = step + 1;
int flag = 0;
for (i = 0; i < n; i++) {
if (w[i] > dis[step][i]) {
sum = sum - w[i] + dis[step][i];
w[i] = dis[step][i];
flag = 1;
}
}
if (flag)
dfs(step + 1, cnt + 1, sum, temp, w);
else
f[step] = 1;
}
}
}
int main() {
int x, y;
scanf("%d%d%d", &n, &m, &k);
for (i = 0; i < n; i++) {
scanf("%d%d", &pos[i].x, &pos[i].y);
}
for (i = 0; i < m; i++) {
scanf("%d%d", &x, &y);
for (j = 0; j < n; j++) {
dis[i][j] = sqrt(pow(x - pos[j].x, 2) + pow(y - pos[j].y, 2));
}
}
int temp[25];
float las_dis[50];
dfs(0, 0, 0, temp, las_dis);
printf("%d", res[0]);
for (i = 1; i < k; i++) {
printf(" %d", res[i]);
}
printf("\n");
return 0;
}
import java.util.Scanner;
public class Main {
static int n,m,k,j,f1,f2;
static int [][]c=new int [55][2];
static int [][]y=new int [27][2];
static int []d=new int [12];
static int []f=new int [55];
static float [][]yc=new float[27][55];
static float s=1000000000;
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int i,j;
int []o=new int[12];
float []w=new float[55];
n=input.nextInt();
m=input.nextInt();
k=input.nextInt();
for(i=1;i<=n;i++)
{
c[i][0]=input.nextInt();
c[i][1]=input.nextInt();;
}
for(i=1;i<=m;i++)
{
y[i][0]=input.nextInt();
y[i][1]=input.nextInt();
for(j=1;j<=n;j++)
yc[i][j]=(float) Math.sqrt((c[j][0]-y[i][0])*(c[j][0]-y[i][0])+(c[j][1]-y[i][1])*(c[j][1]-y[i][1]));
}
dfs(0,1,o,w,0);
for(i=0;i<k;i++)
System.out.print(d[i]+" ");
}
private static void dfs(int t,int i,int o[],float w[],float sum) {
if(i<=m+1)
{
if(t==k)
{
if(sum<s)
{
s=sum;
for(j=0;j<k;j++)
d[j]=o[j];
}
}
else if(i<=m&&t<k)
{
float []ww=new float[55];
for( j=1;j<=n;j++)
ww[j]=w[j];
dfs(t,i+1,o,w,sum);
f1=1;
f2=0;
if(f[i]==0)
{
o[t]=i;
if(t>0)
{
f2=1;
for( j=1;j<=n;j++)
{
if(ww[j]>yc[i][j])
{
sum=sum-ww[j]+yc[i][j];
ww[j]=yc[i][j];
f1=0;
}
}
}
else
{
for( j=1;j<=n;j++)
{
sum+=yc[i][j];
ww[j]=w[j]=yc[i][j];
}
}
if(f1==1&&f2==1)
{
f[i]=1;
dfs(t,i+1,o,w,sum);
}
else
dfs(t+1,i+1,o,ww,sum);
}
}
}
}
}
简记:
显然的最小生成树问题,对于河流,就看成是一个节点,每个点建码头就是向该点连一条边。
注意有坑点:
1.分别跑一次没有河流的n个点的最小生成树和一次有河流的n+1个点的最小生成树
2.边权小于0的边一定要选,只赚不亏。所以只能用kruskal
#include
using namespace std;
const int node_size = 10005;
const int edge_size = 100005;
const int inf = 0x3f3f3f3f;
struct edge {
int s, t, w;
edge(){};
edge(int ss, int tt, int ww) {
s = ss;
t = tt;
w = ww;
}
};
bool operator<(edge l, edge r) { return l.w < r.w; }
struct tree_set {
int fa[node_size], size;
void init(int x) {
size = x;
for (int i = 1; i <= x; i++) {
fa[i] = i;
}
}
int f(int x) {
if (fa[x] != x)
return fa[x] = f(fa[x]);
else
return fa[x];
}
bool Is_connect(int x, int y) { // x,y是否已经相连
if (f(x) == f(y))
return 1;
else
return 0;
}
bool merge(int x, int y) { // x,y两点合并
if (Is_connect(x, y)) return 0; //连接失败,本来就相连
fa[f(x)] = f(y);
return 1;
}
};
struct Graph {
vector<edge> u[node_size];
vector<edge> a;
int n, m; //点数
void add_edge(edge x) {
u[x.s].push_back(x);
int temp = x.s;
x.s = x.t;
x.t = temp;
u[x.s].push_back(x);
a.push_back(x);
}
void clear() {
n = 0, m = 0;
for (int i = 0; i < node_size; i++) {
u[i].clear();
}
a.clear();
}
void input() {
clear();
scanf("%d%d", &n, &m);
int mm = m;
while (mm--) {
int ss, tt, ww;
scanf("%d%d%d", &ss, &tt, &ww);
add_edge(edge(ss, tt, ww));
}
}
bool vis[node_size];
int prim() { //求最小生成树,如果不存在就返回inf
memset(vis, 0, sizeof(vis));
int ret = 0, k = 1;
priority_queue<edge> p;
for (int i = 0; i < u[1].size(); i++) {
p.push(u[1][i]);
}
vis[1] = 1;
while (k < n) {
if (p.empty()) return inf;
edge now = p.top();
while (vis[now.t]) {
p.pop();
if (p.empty()) return inf;
now = p.top();
}
if (vis[now.t]) return inf; //不连通
vis[now.t] = 1;
ret += now.w;
k++;
for (int i = 0; i < u[now.t].size(); i++) {
p.push(u[now.t][i]);
}
}
return ret;
}
bool cmp_kruskal(edge a, edge b) { return a.w < b.w; }
int kruskal() {
int ret = 0, k = 0;
sort(a.begin(), a.end());
tree_set p;
p.init(n);
for (int i = 0; i < a.size(); i++) {
if (a[i].w < 0) {
ret += a[i].w;
k += p.merge(a[i].s, a[i].t);
continue;
}
if (!p.Is_connect(a[i].s, a[i].t)) {
ret += a[i].w;
k += p.merge(a[i].s, a[i].t);
}
if (k == n - 1) return ret;
}
if (k == n - 1)
return ret;
else
return inf;
}
};
int main() {
Graph ans;
int x = inf;
ans.input();
x = ans.kruskal();
// printf("x=%d\n",x);
for (int i = 1; i <= ans.n; i++) {
int temp = 0;
scanf("%d", &temp);
if (temp == -1) continue;
ans.add_edge(edge(i, ans.n + 1, temp));
ans.add_edge(edge(ans.n + 1, i, temp));
}
ans.n++;
printf("%d\n", min(x, ans.kruskal()));
return 0;
}
import java.util.*;
import java.io.*;
import java.math.*;
class edge{
int a,b,v;
public edge(int A,int B,int V){
a=A;
b=B;
v=V;
}
}
public class Main {
static StreamTokenizer cin=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
static int f[]=new int[11000];
static int w[]=new int[11000];
static long ans=0,ans1=0;
public static int Int() throws IOException{
cin.nextToken();
return (int)cin.nval;
}
public static int find(int x){
if(x==f[x])return x;
f[x]=find(f[x]);
return f[x];
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
int n,m;
int INF=1<<30;
edge e[]=new edge[110000];
n=Int();
m=Int();
Comparator<edge> order = new Comparator<edge>(){
public int compare(edge o1, edge o2) {
// TODO Auto-generated method stub
if(o1.v > o2.v)
{
return 1;
}
else if(o1.v < o2.v)
{
return -1;
}
else
{
return 0;
}
}
};
Queue<edge> que=new PriorityQueue(m+n,order);
Queue<edge> que1=new PriorityQueue(m+n,order);
for(int i=0;i<m;i++){
int a=Int();
int b=Int();
int v=Int();
e[i]=new edge(a,b,v);
que.add(e[i]);
}
f[0]=0;
for(int i=1;i<=n;i++){
f[i]=i;
w[i]=Int();
if(w[i]==-1)w[i]=INF;
edge x=new edge(0,i,w[i]);
que.add(x);
}
for(int q=0;q<m+n;q++){
edge x=que.poll();
que1.add(x);
int X=find(x.a);
int Y=find(x.b);
if(f[X]==f[Y]){
if(x.v<0)ans+=x.v;
continue;
}
ans+=x.v;
f[X]=Y;
}
for(int i=0;i<=n;i++)f[i]=i;
for(int q=0;q<m+n;q++){
edge x=que1.poll();
if(x.a==0)continue;
int X=find(x.a);
int Y=find(x.b);
if(f[X]==f[Y]){
if(x.v<0)ans1+=x.v;
continue;
}
ans1+=x.v;
f[X]=Y;
}
int t=find(1);
for(int i=2;i<=n;i++){
int y=find(i);
if(f[y]!=t){
t=-1;
break;
}
}
if(t==-1)
System.out.println(ans);
else System.out.println(Math.min(ans, ans1));
}
}
简记:算是挺经典的问题了,算一个500500的矩阵的最大子矩阵,相当于枚举使用哪些行O(nn),对每次枚举,求最大子段和O(m)
#include
using namespace std;
#define maxn 505
#define inf 0x3f3f3f3f
int sum[maxn][maxn];
int main() {
int n, m, x;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &x);
sum[i][j] = sum[i - 1][j] + x;
}
}
int ans = -inf;
for (int l = 1; l <= n; l++) {
for (int r = l; r <= n; r++) {
int dp = 0;
for (int i = 1; i <= m; i++) {
int t = sum[r][i] - sum[l - 1][i];
if (dp > 0)
dp += t;
else
dp = t;
if (dp > ans) ans = dp;
}
}
}
printf("%d\n", ans);
return 0;
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
int n = (int)in.nval;
in.nextToken();
int m = (int)in.nval;
int[][] a = new int[n][m];
int i,j;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
in.nextToken();
a[i][j]=(int)in.nval;
}
}
int max = maxSum(a);
System.out.print(max);
}
private static int maxSum(int[][] a) {
if(a==null||a.length==0||a[0].length==0){
return 0;
}
int max = Integer.MIN_VALUE;
int cur = 0;
int[] s = null;
int i,j,k;
int leni=a.length;
int lenj=a[0].length;
for(i=0;i!=leni;i++){
s = new int[lenj];
int lens = s.length;
for(j=i;j!=leni;j++){
cur=0;
for(k=0;k!=lens;k++){
s[k] += a[j][k];
cur +=s[k];
max = Math.max(max, cur);
cur = cur < 0 ? 0 :cur;
}
}
}
return max;
}
}
简记:分类讨论,挺麻烦的,一定要谨慎。
#include
using namespace std;
const int maxn = 150;
int n;
struct point {
int x, dir;
} a[maxn], s;
bool operator<(point x, point y) { return x.x < y.x; }
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
int x;
scanf("%d", &x);
a[i].dir = x / abs(x);
a[i].x = abs(x);
}
s = a[0];
sort(a, a + n);
int ans = 0;
/*for(int i=0;i
if (s.dir == 1) { //向右
int pos = -1, c;
bool flag = 0;
for (int i = 0; i < n; i++) {
if (a[i].x == s.x && a[i].dir == s.dir) {
pos = i;
break;
}
}
for (int i = pos + 1; i < n; i++) {
if (a[i].dir * s.dir == -1) {
ans++;
if (flag == 0) {
c = i;
flag = 1;
}
}
}
if (flag == 1) {
for (int i = c - 1; i >= 0; i--) {
if (a[i].dir == s.dir && a[i].x == s.x) continue;
if (a[i].dir * a[c].dir == -1) ans++;
}
}
} else {
int pos = -1, c;
bool flag = 0;
for (int i = 0; i < n; i++) {
if (a[i].x == s.x && a[i].dir == s.dir) {
pos = i;
break;
}
}
for (int i = pos - 1; i >= 0; i--) {
if (a[i].dir * s.dir == -1) {
ans++;
if (flag == 0) {
c = i;
flag = 1;
}
}
}
// printf("ans=%d\n",ans);
if (flag == 1) {
for (int i = c + 1; i < n; i++) {
if (a[i].dir == s.dir && a[i].x == s.x) continue;
if (a[i].dir * a[c].dir == -1) ans++;
}
}
}
printf("%d\n", ans + 1);
return 0;
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(System.out);
static int n;
public static void main(String[] args) throws Exception {
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
int f = 0, l = 0, r = 0;
s = br.readLine().split(" ");
f = Integer.parseInt(s[0]);
for (int i = 1; i < n; i++) {
int x = Integer.parseInt(s[i]);
if (Math.abs(x) < Math.abs(f) && x > 0) r++;
if (Math.abs(x) > Math.abs(f) && x < 0) l++;
}
if (f < 0 && r == 0 || f > 0 && l == 0) pw.println(1);
else pw.print(l + r + 1);
pw.flush();
pw.close();
br.close();
}
}
简记:
1.状态设定: d p ( i , j , k , h ) dp(i,j,k,h) dp(i,j,k,h)表示在点 ( i , j ) (i,j) (i,j),当前手里有 k k k个物品,最大的为 h h h的路径数。
2.状态转移方程:
d p ( i , j , k , h ) = 选 c ( i , j ) + 不 选 c ( i , j ) ; dp(i,j,k,h)=选c(i,j) +不选c(i,j); dp(i,j,k,h)=选c(i,j)+不选c(i,j);
选 c ( i , j ) : d p ( i − 1 , j , k − 1 , [ 0 , h − 1 ] ) + d p ( i , j − 1 , k − 1 , [ 0 , h − 1 ] ) 前 提 h = = c ( i , j ) & & k ! = 0 选c(i,j):dp(i-1,j,k-1,[0,h-1])+dp(i,j-1,k-1,[0,h-1]) 前提 h==c(i,j) \&\& k!=0 选c(i,j):dp(i−1,j,k−1,[0,h−1])+dp(i,j−1,k−1,[0,h−1])前提h==c(i,j)&&k!=0
不 选 c ( i , j ) : d p ( i − 1 , j , k , h ) + d p ( i , j − 1 , k , h ) ; 不选c(i,j):dp(i-1,j,k,h)+dp(i,j-1,k,h); 不选c(i,j):dp(i−1,j,k,h)+dp(i,j−1,k,h);
3.初始状态:
d p ( 0 , 0 , 0 , 0 ) = 1 ; dp(0,0,0,0)=1; dp(0,0,0,0)=1;
d p ( 0 , 0 , 1 , c ( 0 , 0 ) ) = 1 ; dp(0,0,1,c(0,0))=1; dp(0,0,1,c(0,0))=1;
一个坑点:有的礼物价值会为 0 0 0,转移过程会出问题,解决办法: c [ i ] [ j ] + + ; c[i][j]++; c[i][j]++;
#include
using namespace std;
#define MOD 1000000007
#define mod(x) ((x) % MOD)
const int bas = 55;
const int maxn = 15;
typedef long long int qq;
qq dp[bas][bas][bas][maxn];
int n, m, p, c[bas][bas], w;
int main() {
while (scanf("%d%d%d", &n, &m, &p) != EOF) {
w = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &c[i][j]);
c[i][j]++;
w = max(w, c[i][j]);
}
}
memset(dp, 0, sizeof(dp));
dp[1][1][0][0] = 1;
dp[1][1][1][c[1][1]] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (i == 1 && j == 1) continue;
for (int k = 0; k <= p; k++) {
for (int h = 0; h <= w; h++) {
dp[i][j][k][h] = 0;
if (c[i][j] == h && k != 0) { //选c[i][j]
for (int u = 0; u < h; u++) {
dp[i][j][k][h] += dp[i - 1][j][k - 1][u] +
dp[i][j - 1][k - 1][u];
}
}
dp[i][j][k][h] =
mod(dp[i][j][k][h] + dp[i - 1][j][k][h] +
dp[i][j - 1][k][h]);
}
}
}
}
qq ans = 0;
for (int i = 0; i <= w; i++) {
ans += dp[n][m][p][i];
}
printf("%lld\n", mod(ans));
}
return 0;
}
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Main
{
private static StreamTokenizer tokenizer = new StreamTokenizer(
new InputStreamReader(System.in));
private static PrintWriter outWriter = new PrintWriter(
new OutputStreamWriter(System.out));
private static int n, m, k;
private static int[][] table;
private static final int MOD = 1000000007;
private static long[][][][] state;
private static long dfs(int i, int j, int num, int max)
{
if (state[i][j][num][max] != -1)
return state[i][j][num][max];
long currentAns = 0;
if (i == n - 1 && j == m - 1)
{
if (num == k || max < table[i][j] && num + 1 == k)
currentAns++;
state[i][j][num][max] = currentAns;
return currentAns;
}
if (i + 1 < n)
{
currentAns += dfs(i + 1, j, num, max);
if (max < table[i][j] && num + 1 <= k)
currentAns += dfs(i + 1, j, num + 1, table[i][j]);
}
if (j + 1 < m)
{
currentAns += dfs(i, j + 1, num, max);
if (max < table[i][j] && num + 1 <= k)
currentAns += dfs(i, j + 1, num + 1, table[i][j]);
}
state[i][j][num][max] = currentAns;
return currentAns;
}
public static void main(String[] args) throws Exception
{
tokenizer.nextToken();
n = (int) tokenizer.nval;
tokenizer.nextToken();
m = (int) tokenizer.nval;
tokenizer.nextToken();
k = (int) tokenizer.nval;
table = new int[n][m];
state = new long[n][m][k + 1][14];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
for (int t = 0; t <= k; t++)
Arrays.fill(state[i][j][t], -1);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
tokenizer.nextToken();
table[i][j] = (int) tokenizer.nval;
table[i][j]++;
}
long ret = dfs(0, 0, 0, 0);
outWriter.println(ret % MOD);
outWriter.flush();
}
}
简记:
数论类技巧公式,可以打表找规律
g ( x ) = ∑ i = 1 x f ( i ) = f ( n + 2 ) − 1 ; g(x)=\sum_{i=1}^{x}f(i)=f(n+2)-1; g(x)=∑i=1xf(i)=f(n+2)−1;
f ( n ) % f ( m ) = f ( n % m ) ∗ f ( m − 1 ) ⌊ n m ⌋ ; f(n)\%f(m)=f(n\%m)*f(m-1)^{\lfloor\frac nm\rfloor}; f(n)%f(m)=f(n%m)∗f(m−1)⌊mn⌋;
样例没过,但是满分了,最后一点很复杂的分类讨论不想看了~
#include
using namespace std;
typedef long long int qq;
#define mod(x, P) ((x) % P)
#define moc(x, P) (((x) >= P) ? ((x) - (P)) : (x))
struct Mat {
qq a[2][2];
} o, e, u;
qq n, m, p;
qq fast_mul(qq x, qq y, qq p) {
qq ret = 0;
x = mod(x, p);
y = mod(y, p);
while (x > 0) {
if (x & 1) ret = moc(ret + y, p);
x >>= 1;
y = moc(y << 1, p);
}
return ret;
}
qq fast_pow(qq x, qq k, qq p) {
qq ret = 1;
x = mod(x, p);
while (k > 0) {
if (k & 1) ret = fast_mul(ret, x, p);
k >>= 1;
x = fast_pow(x, x, p);
}
return moc(ret, p);
}
Mat operator*(Mat x, Mat y) {
Mat ret = o;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
ret.a[i][j] =
moc(ret.a[i][j] + fast_mul(x.a[i][k], y.a[k][j], p), p);
}
}
}
return ret;
}
Mat operator^(Mat x, qq k) {
Mat ret = e;
while (k > 0) {
if (k & 1) ret = ret * x;
k >>= 1;
x = x * x;
}
return ret;
}
void init() {
e.a[0][0] = 1;
e.a[0][1] = 0;
e.a[1][0] = 0;
e.a[1][1] = 1;
o.a[0][0] = 0;
o.a[0][1] = 0;
o.a[1][0] = 0;
o.a[1][1] = 0;
u.a[0][0] = 1;
u.a[0][1] = 1;
u.a[1][0] = 1;
u.a[1][1] = 0;
}
qq f(qq x) {
Mat ret;
ret = u ^ (x - 1);
return ret.a[0][0];
}
qq real(qq n, qq m) {
qq a = n % m;
if (a % 2) return f(m - a);
return ((f(m) - f(m - a)) % p + p) % p;
}
qq solve(qq n, qq m) {
qq t1 = n / m;
if (m % 2) {
if (!t1 % 2 && !t1 % 4) return f(n % m);
if (!t1 % 2 && t1 % 4) return ((f(m) - f(n % m)) % p + p) % p;
if (t1 % 2 && !t1 % 4) return real(n, m);
if (t1 % 2 && t1 % 4) return ((f(m) - real(n, m)) % p + p) % p;
} else {
if (t1 % 2)
return real(n, m);
else
return f(n % m);
}
}
qq get_value(qq n, qq m) {
n += 2;
qq a = solve(n, m);
if (!a)
return f(m) - 1;
else
return a - 1;
}
int main() {
init();
while (scanf("%lld%lld%lld", &n, &m, &p) != EOF) {
qq ans = get_value(n, m);
printf("%lld\n", ans);
}
return 0;
}
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
static BigInteger[][] cal_fm = { { new BigInteger("1"), new BigInteger("1") },
{ new BigInteger("1"), new BigInteger("0") } };
static BigInteger[][] cal_sum = { { new BigInteger("2"), new BigInteger("0"), new BigInteger("-1") },
{ new BigInteger("1"), new BigInteger("0"), new BigInteger("0") },
{ new BigInteger("0"), new BigInteger("1"), new BigInteger("0") } };
static BigInteger[][] MOD = { { new BigInteger("1") }, { new BigInteger("1") } };
static BigInteger[][] SUM = { { new BigInteger("4") }, { new BigInteger("2") }, { new BigInteger("1") } };
private static BigInteger[][] mult(BigInteger[][] cal_fm2, BigInteger[][] mOD2, BigInteger p, boolean flag) {
int i_max = cal_fm2.length;
int j_max = mOD2[0].length;
int k_max = cal_fm2[0].length;
if (k_max != mOD2.length) {
return null;
}
BigInteger[][] ans = new BigInteger[i_max][j_max];
for (int i = 0; i < i_max; i++) {
for (int j = 0; j < j_max; j++) {
BigInteger sum = new BigInteger("0");
for (int k = 0; k < k_max; k++) {
if (flag) {
sum = (sum.mod(p)).
add(cal_fm2[i][k].multiply(mOD2[k][j]).
mod(p)).
mod(p);
} else {
sum = (sum.add(cal_fm2[i][k].multiply(mOD2[k][j])));
}
}
if (flag) {
ans[i][j] = sum.mod(p);
} else {
ans[i][j] = sum;
}
}
}
return ans;
}
public static String fib(long n, long m, long p) {
BigInteger mod = new BigInteger("0");
BigInteger sum = new BigInteger("0");
if (m > n + 2) {
if (n == 1) {
sum = new BigInteger("1");
} else {
n = n - 1;
while (n != 0) {
// System.out.println(n);
if ((n & 1) == 1) {
SUM = mult(cal_sum, SUM, new BigInteger(String.valueOf(p)), true);
}
n = n >> 1;
cal_sum = mult(cal_sum, cal_sum, new BigInteger(String.valueOf(p)), true);
}
sum = SUM[2][0];
}
// System.out.println(sum);
return sum.mod(new BigInteger(String.valueOf(p))).toString();
} else {
if (m == 1 || m == 2) {
mod = new BigInteger("1");
} else {
m = m - 1;
while (m != 0) {
if ((m & 1) == 1) {
MOD = mult(cal_fm, MOD, new BigInteger(String.valueOf(p)), false);
}
m = m >> 1;
cal_fm = mult(cal_fm, cal_fm, new BigInteger(String.valueOf(p)), false);
}
mod = MOD[1][0];
}
if (n == 1) {
sum = new BigInteger("1");
} else {
n = n - 1;
while (n != 0) {
if ((n & 1) == 1) {
SUM = mult(cal_sum, SUM, mod, true);
}
n = n >> 1;
cal_sum = mult(cal_sum, cal_sum, mod, true);
}
sum = SUM[2][0];
}
return sum.mod(new BigInteger(String.valueOf(p))).toString();
}
}
public static void main(String[] args) {
long n, m, p;
Scanner scanner = new Scanner(System.in);
n = scanner.nextLong();
m = scanner.nextLong();
p = scanner.nextLong();
System.out.println(fib(n, m, p));
}
}
简记:简单dp,时间复杂度O(n*n)
#include
typedef long long LL;
using namespace std;
const int MOD = 1e8 + 7;
LL dp[1005][1005], tmp1, tmp2;
int main() {
LL n, s, a, b;
cin >> n >> s >> a >> b;
dp[1][(s % n + n) % n] = 1;
for (int i = 1; i < n; i++) {
tmp1 = b * (n - i) % n;
tmp2 = a * (n - i) % n;
for (int j = 0; j < n; j++) {
dp[i + 1][(j + tmp1) % n] =
(dp[i + 1][(j + tmp1) % n] + dp[i][j]) % MOD;
dp[i + 1][(j - tmp2 + n) % n] =
(dp[i + 1][(j - tmp2 + n) % n] + dp[i][j]) % MOD;
}
}
cout << dp[n][0] << endl;
return 0;
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(System.out);
static int N = 1010, n, s, a, b, MOD = (int) (1e8 + 7);
static int f[][] = new int[N][N];
public static void main(String[] args) throws IOException {
String ss[] = br.readLine().split(" ");
n = Integer.parseInt(ss[0]);
s = Integer.parseInt(ss[1]);
a = Integer.parseInt(ss[2]);
b = Integer.parseInt(ss[3]);
f[0][0] = 1;
for (int i = 1; i < n; i++) {
for (int j = 0; j < n; j++) {
f[i][j] = (f[i - 1][mod(j - a * i, n)] + f[i - 1][mod(j + b * i, n)]) % MOD;
}
}
pw.print(f[n - 1][mod(s, n)]);
pw.flush();
pw.close();
br.close();
}
public static int mod(int a, int b) {
return (a % b + b) % b;
}
}