二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。
对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为:
( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根
小易想知道最多可以放多少块蛋糕在网格盒子里。
每组数组包含网格长宽W,H,用空格分割.(1 ≤ W、H ≤ 1000)
输出一个最多可以放的蛋糕数
3 2
4
//把所有的行和列排成一行(与原来等价) 那么问题就变成了将蛋糕每隔一个空放一个 可以多少
import java.util.*;
public class PutCakeNum{
public static int deal(int r, int c){
int n=0;
if(r%4==0||c%4==0){n=r*c/2;}//如果能整除4 那么蛋糕个数为网格个数的一半
else{ n=r*c/2+1;}//不能被4整除 将蛋糕每隔一个空放一个 可以放多少 奇数的一半+1
return n;
}
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int r=sc.nextInt();
int c=sc.nextInt();
int res=deal(r,c);
System.out.println(res);
}
}
} //这个题画图可以知道,其实是循环的,每四行四列循环一次,因此整个盒子被分成四块区域,
//分别计算四块区域即可
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int w = sc.nextInt();
int h = sc.nextInt();
int sum = 0;
int w0 = w/4;
int h0 = h/4;
int w1 = w%4;
int h1 = h%4;
sum += w0*h0*8;
sum += 2*w1*h0;
sum += 2*h1*w0;
if(w1<=2 && h1<=2){
sum += w1*h1;
}else if(w1==3 && h1==3){
sum += 5;
}else if(w1<=2 && h1==3){
sum += 2*w1;
}else if(w1==3 && h1<=2){
sum += 2*h1;
}
System.out.println(sum);
}
}
}
//package com.gulamjan.t009.不要二;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int W = in.nextInt();
int H = in.nextInt();
System.out.println(cakeNum(W, H));
}
in.close();
}
public static int cakeNum(int W ,int H) {
int result = 0;
if (W % 4 == 0 || H % 4 == 0) {
result = W * H / 2;
}else {
result = W * H / 2 + 1;
}
return result;
}
}
import sys x,y=list(map(int, sys.stdin.readline().split())) if x % 4 == 0 or y % 4 == 0:print(int(x*y//2)) elif x % 2 == 0 and y % 2 == 0:print(((x*y)//2+1) + 1) else:print(x*y//2 + 1)
把图像画出来就规律就明显了
还有我感觉为什么py3每次都比py2运行时间长,都是同样的思路。
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int len,wid;
scanf("%d %d",&len,&wid);
int sum=0;
while(len>0&&wid>0){
int len1=len/4;
int len2=len%4;
int wid1=wid/4;
int wid2=wid%4;
if(len2>1) len2=2;
if(wid2>1) wid2=2;
if(wid<2||len<2) //注意特殊情况!!!
sum+=(2*len1+len2)*(wid1*2+wid2);
else sum+=(2*len1+len2)*(wid1*2+wid2)-(2*len1+len2-2)*(wid1*2+wid2-2);
len-=2;
wid-=2;
}
printf("%d",sum);
return 0;
}
思路就是一圈一圈往里减少
import java.util.*;
public class Main{
static class Cake {
int x;
int y;
boolean isFlag;
public Cake(int x, int y, boolean isFlag) {
this.x = x;
this.y = y;
this.isFlag = isFlag;
}
public void setFlag(boolean flag) {
isFlag = flag;
}
}
static int count = 0;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int w = scanner.nextInt();
int h = scanner.nextInt();
count = w*h;
List<List<Cake>> lists = new ArrayList<>();
for (int i = 0; i < h; i++) {
List<Cake> list = new ArrayList<>();
for (int j = 0; j < w; j++) {
list.add(new Cake(i,j,true));
}
list.add(null);
list.add(null);
lists.add(list);
}
lists.add(null);
lists.add(null);
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
Cake curCake = lists.get(i).get(j);
if (!curCake.isFlag ){
continue;
}
Cake rightCake = lists.get(i).get(j + 2);
if (rightCake != null && rightCake.isFlag){
rightCake.setFlag(false);
count--;
}
List listLevel = lists.get(i + 2);
if (listLevel != null ){
Cake topCake = lists.get(i + 2).get(j);
if (topCake.isFlag){
topCake.setFlag(false);
count--;
}
}
}
}
System.out.println(count);
}
} import java.util.Scanner; /*思路:这个蛋糕要从第一个位置开始放。同时放蛋糕的情况是可以每四行一个循环,每四列一个循环。
我们可以先算出前面四行的情况,后边就是循环问题了,就都解答出来了。
其实前面四行中,前面两行的情况一样,后边两行情况也是相同的。所以就把前面两行区分为了1,2行和3,4行。
比如针对第一行:算出前面四列情况,后边就根据循环来算出这一行总的蛋糕数量。
那么第3,4行和第1,2行还有一个关系,就是sum12+sum34=纵向数量
*/ public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int m = sc.nextInt(); int n = sc.nextInt(); int a = m / 4;// 横坐标除4取整 int b = m % 4;// 横坐标取余 int c = n / 4;// 纵坐标除4取整 int d = n % 4;// 纵坐标取余 int sum12 = 0;//前边两行放的蛋糕数量一样 int sum34 = 0;//3,4行蛋糕数量也一样 int sum = 0;最后的总的蛋糕数量 int sum1234 = 0;前边四行的蛋糕数量 // 先得出前四行分别的数目,首先前面两行一样,后边两行一样 // 首先是1,2两行放的蛋糕都一样 if (d == 1) { sum12 = c * 2 + 1; } else if (d == 0) { sum12 = (c - 1) * 2 + 2; } else { sum12 = c * 2 + 2; } // 然后是3,4两行,放的蛋糕都一样 sum34 = n - sum12; // 前面四行一共放蛋糕数量如下 sum1234 = 2 * (sum12 + sum34); // 前边计算了前面四行分别的数目,接下来是往纵看, if (b == 1) { sum = a * sum1234 + sum12; }else if (b == 2) { sum = a * sum1234 + 2 * sum12; }else if (b == 3) { sum = a * sum1234 + sum12 * 2 + sum34; } else { sum = a * sum1234; } System.out.println(sum); } } }
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000+10;
int done[maxn][maxn];
int main()
{
int w,h;
scanf("%d%d",&w,&h);
memset(done,0,sizeof(done));
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
{
if(done[i][j]==0) {
done[i][j]=1;
done[i][j+2]=done[i+2][j]=-1;
}
}
int solve=0;
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if(done[i][j]==1) solve++;
cout<<solve<<endl;
return 0;
}
#include<iostream>
using namespace std;
int main()
{
int m, n;
cin >> m >> n;
int num1, num2, line1, line2;
//算出两种模式,每行有多少块蛋糕
if (m % 4 == 0) num1 = num2 = m / 2;
if (m % 4 == 1) { num1 = m / 2 + 1; num2 = m / 2; }
if (m % 4 == 2) { num1 = (m - 2) / 2 + 2; num2 = num1 - 2; }
if (m % 4 == 3) { num1 = (m - 3) / 2 + 2; num2 = num1 - 1; }
//算出这两种模式分别有多少行
if (n % 4 == 0) { line1 = line2 = n/2; }
if (n % 4 == 1) { line1 = n/2+1; line2 = n/2; }
if (n % 4 == 2) { line1 = n/2+1; line2 =(n-2)/2 ; }
if (n % 4 == 3) { line1 =(n-3)/2+2 ; line2 = line1-1; }
//cout << num1 << "*" << line1 << "+" << num2 << "*" << line2 << "=";
cout << num1*line1 + num2*line2;
return 0;
}
#include <stdio.h>
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
bool mark[2000][2000];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
mark[i][j]=false;
}
}
int sum=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(mark[i][j]==true) continue;
else{
sum++;
mark[i][j]=mark[i-2][j]=mark[i+2][j]=mark[i][j-2]=mark[i][j+2]=true;
}
}
}
printf("%d\n",sum);
}
return 0;
}
#include<iostream>
using namespace std;
int main()
{
int W,H;
while(cin >> W >> H)
{
int divofW, divofH, modofW, modofH, cnt = 0;
divofW = W / 4;
divofH = H / 4;
modofW = W % 4;
modofH = H % 4;
cnt += divofW * divofH * 2 * 4;
cnt += modofW * 2 * divofH;
cnt += modofH * 2 * divofW;
if(modofW >= 3 && modofH >= 3)
cnt += 5;
else if(modofW >= 2 && modofH >=2)
cnt += 4;
else if((modofW == 2 && modofH ==1) || (modofW ==1 && modofH ==2))
cnt += 2;
else if(modofW >=1 && moofH >= 1)
cnt += 1;
cout << cnt << endl;
}
return 0;
}
import java.util.Scanner;
public class Main{
public static void main(String[] args){
// 填充法, 只要当前格没有蛋糕并且其四周间隔为2的位置也没蛋糕, 就在此格子上放个蛋糕并标记
Scanner in = new Scanner(System.in);
int w = in.nextInt();
int h = in.nextInt();
boolean[][] visited = new boolean[h][w];
int count = 0;
for (int i = 0; i < h; ++i) {
for (int j = 0; j < w; ++j) {
if(visited[i][j] == true)
continue;
else{
if(j-2 < 0 || visited[i][j-2] != true){
if(j+2 >= w || visited[i][j+2] != true){
if(i-2 < 0 || visited[i-2][j] != true){
if(i+2 >= h || visited[i+2][j] != true){
++count;
visited[i][j] = true;
}
}
}
}
}
}
}
System.out.println(count);
}
}