java实现点选汉字验证码(自己修改后的)
参考:http://blog.csdn.net/qq_26680031/article/details/51168527
- package com.rd.p2p.web;
- import java.awt.BasicStroke;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics;
- import java.awt.Graphics2D;
- import java.awt.geom.AffineTransform;
- import java.awt.geom.Line2D;
- import java.awt.image.BufferedImage;
- import java.io.IOException;
- import java.io.UnsupportedEncodingException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Random;
- import javax.imageio.ImageIO;
- import javax.servlet.ServletOutputStream;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.poi.ss.formula.functions.T;
- import org.apache.struts2.convention.annotation.Action;
- import com.alibaba.fastjson.JSON;
- import com.rd.p2p.additional.redisCaptcha.util.ResponseUtil;
- import com.rd.p2p.common.util.redis.RedisValidImgCodeUtils;
- import com.rd.p2p.core.core.Global;
- import com.rd.p2p.core.core.constant.Constant;
- import com.rd.p2p.core.core.web.BaseAction;
- public class CodeAction extends BaseAction<T> {
- private static final String KEY = "randomCode";
- //点选文字图片验证码刷新次数
- private static final String KEY_TOTAL = "select_random_code_total";
- //点选文字图片验证码验证通过次数
- private static final String KEY_SUCC = "select_random_code_succ";
- //点选文字图片验证码验证失败次数
- private static final String KEY_FAIL = "select_random_code_fail";
- //缓存时间单位秒 设置成7天
- private static final int CACHE_SECONDS = 604800;
- //定义点选文字图片验证码允许的误差值
- private static final int ERROR_AMOUNT = 12;// 定义允许的误差值,单位是px
- //生成汉字的个数
- private static Integer[] arr = new Integer[] {1, 2, 3, 4, 5};
- //汉字颜色随机范围
- private static Color[] colors = {Color.GRAY, Color.LIGHT_GRAY, Color.CYAN};
- /**
- * 跳转页面
- * @return
- */
- @Action("/verification")
- public String verification() {
- request.setAttribute("web_url", Global.getString("web_url"));
- return "verification";
- }
- /**生成验证码
- * @param src
- * @param x
- * @param y
- */
- @Action("/code/getVerificationCode")
- public void readUsingImageReaderBigcH() {
- ServletOutputStream outStream = null;
- try {
- // http://localhost:8080/gtop/img/149679.jpg
- //String url = "d:/4.png";
- //url = request.getSession().getServletContext().getRealPath("") + url;
- /* InputStream source = new FileInputStream(src);
- BufferedImage image = null;
- image = ImageIO.read(source);*/
- //生成背景图片
- BufferedImage image = getBackGround();
- int hight = image.getHeight();
- Graphics graphics = image.getGraphics();
- // 设置颜色
- graphics.setColor(Color.red);
- graphics.setFont(new Font("宋体", Font.BOLD, 30));
- StringBuilder sb = new StringBuilder();
- Random random = new Random();
- //转成集合
- List<Integer> intList = Arrays.asList(arr);
- //重新随机排序
- Collections.shuffle(intList);
- //list参数坐标参数 用于校验是否验证通过
- List<String> codeList = new ArrayList<String>();
- int x = 0;
- int y = 0;
- //定义随机1到arr.length某一个字不参与校验
- int num = random.nextInt(arr.length)+1;
- for (int i = 0; i < arr.length; i++) { // 5个汉字,只点4个
- String ch = getRandomChineseChar();
- int place = intList.get(i);
- if (place == 1) {
- x = new Random().nextInt(30) + 40; // 自己定义的位子坐标
- y = new Random().nextInt(30) + 40; // i=1的时候,y的值
- }
- if (place == 2) {
- x = new Random().nextInt(40) + 120; // 自己定义的位子坐标
- y = new Random().nextInt(30) + 50; // i=2的时候,y的值
- }
- if (place == 3) {
- x = new Random().nextInt(70) + 200; // 自己定义的位子坐标
- y = new Random().nextInt(50) + 100; // i=3的时候,y的值
- }
- if (place == 4) {
- x = new Random().nextInt(70) + 80; // i=4的时候,x的值
- y = new Random().nextInt(30) + 90; // 自己定义的位子坐标
- }
- if (place == 5) {
- x = new Random().nextInt(70) + 180; // i=4的时候,x的值
- y = new Random().nextInt(30) + 50; // 自己定义的位子坐标
- }
- Constant.LOGGER.info("x:" + x + ",y:" + y + ",hight:" + hight);
- //字体颜色
- graphics.setColor(colors[random.nextInt(colors.length)]);
- graphics.drawString(ch, x, y);
- if (place != num) {
- sb.append(ch);
- codeList.add(x + "_" + y); // jsp页面坐标原点在字的中间,drawString方法坐标原点在中间
- }
- }
- Constant.LOGGER.info("汉字:" + sb);
- //放入session
- //将产生的随机汉字验证码存进session中进行保存
- String sessionid = request.getSession().getId();
- RedisValidImgCodeUtils.save(sessionid + KEY, codeList);
- //增加验证码请求次数
- RedisValidImgCodeUtils.increment(KEY_TOTAL, CACHE_SECONDS);
- // 可以将图片合并传入前端 也可以直接传数据汉字给前端
- // 创建顶部图片
- BufferedImage bi = new BufferedImage(image.getWidth(), 25, BufferedImage.TYPE_INT_RGB);
- Graphics gra = bi.getGraphics();
- // 设置背景颜色
- gra.setColor(Color.WHITE);
- // 填充区域
- gra.fillRect(0, 0, bi.getWidth(), bi.getHeight());
- // 设置边框颜色
- gra.setColor(Color.BLUE);
- // 设置边框区域
- gra.drawRect(1, 1, bi.getWidth() - 2, bi.getHeight() - 2);
- // 设置文字背景颜色
- Font font = new Font("Microsoft YaHei", Font.BOLD, 16);
- gra.setFont(font);
- gra.setColor(Color.BLACK);
- gra.drawString("按顺序点击:" + sb.toString(), (bi.getWidth() - 10*font.getSize())/2, bi.getHeight()/2 + font.getSize()/2);//设置文字字体 与位子 居中
- BufferedImage combined = new BufferedImage(image.getWidth(), image.getHeight() + bi.getHeight(), BufferedImage.TYPE_INT_RGB);
- Graphics g = combined.getGraphics(); //合并
- g.drawImage(bi, 0, 0, null);
- g.drawImage(image, 0, bi.getHeight(), null);
- outStream= response.getOutputStream();
- ImageIO.write(combined, "jpg", outStream);
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (outStream != null) {
- outStream.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- @Action("/code/verify")
- public void verify() throws IOException {
- Map<String, Object> data = new HashMap<String, Object>();
- data.put("result", false);
- String value = request.getParameter("code");
- String sessionid = request.getSession().getId();
- if (RedisValidImgCodeUtils.get(sessionid + KEY) == null) {
- printWebJson(JSON.toJSONString(data));
- return;
- }
- List<String> sValue = (List<String>) RedisValidImgCodeUtils.get(sessionid + KEY);
- //取到数据后直接清掉redis
- RedisValidImgCodeUtils.del(sessionid + KEY);
- Constant.LOGGER.info("**前端请求数据***"+value);
- Constant.LOGGER.info("**后端实际数据**"+sValue.toString());
- //为null 或者"" 或者 " "
- if (StringUtils.isBlank(value) || sValue == null || sValue.size() < 1) {
- printWebJson(JSON.toJSONString(data));
- return;
- }
- String [] valueStr = value.split(",");
- if(valueStr.length != sValue.size() || valueStr.length != 4){
- printWebJson(JSON.toJSONString(data));
- return;
- }
- /*判断坐标参数是否正确*/
- String str = "";
- for (int i = 0; i < valueStr.length; i++) {
- str = valueStr[i].toString();
- if(StringUtils.isBlank(str) || StringUtils.isBlank(sValue.get(i).toString())){
- printWebJson(JSON.toJSONString(data));
- return;
- }
- String [] vL = valueStr[i].toString().split("_");
- String [] svL = sValue.get(i).toString().split("_");
- if(vL.length != svL.length || svL.length != 2){
- printWebJson(JSON.toJSONString(data));
- return;
- }
- //x轴 y轴判断 坐标点在左上角 ,图片宽度30px 点击范围扩大12px, 范围在 x-13 < x <x+13 ;
- if(!(Integer.parseInt(svL[0])-ERROR_AMOUNT < Integer.parseInt(vL[0])-15 && Integer.parseInt(vL[0])-15 < Integer.parseInt(svL[0])+ERROR_AMOUNT )
- || !(Integer.parseInt(svL[1])-ERROR_AMOUNT < Integer.parseInt(vL[1])-15 && Integer.parseInt(vL[1])-15 < Integer.parseInt(svL[1])+ERROR_AMOUNT)){
- //增加验证失败次数
- RedisValidImgCodeUtils.increment(KEY_FAIL, CACHE_SECONDS);
- printWebJson(JSON.toJSONString(data));
- return;
- }
- }
- //增加验证通过次数
- RedisValidImgCodeUtils.increment(KEY_SUCC, CACHE_SECONDS);
- data.put("result", true);
- printWebJson(JSON.toJSONString(data));
- }
- /**
- * 生成背景图片
- * @return
- */
- public BufferedImage getBackGround(){
- int width=300; //指定生成验证码的宽度
- int height=200; //指定生成验证码的高度
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- Graphics g = image.getGraphics();
- Graphics2D g2d = (Graphics2D)g; //创建Graphics2D对象
- Random random = new Random();
- // Font mFont = new Font("黑体", Font.BOLD, 16); //定义字体样式
- // g.setColor(getRandColor(200, 250)); //背景色
- g.fillRect(0, 0, width, height); //绘制背景
- // g.setFont(mFont); //设置字体
- g.setColor(getRandColor(180, 200)); //线条色
- //绘制88根位置和颜色全部为随机产生的线条,该线条为2f
- for (int i = 0; i < 88; i++) {
- int x = random.nextInt(width-1);
- int y = random.nextInt(height-1);
- int x1 = random.nextInt(100)+1;
- int y1 = random.nextInt(120)+1;
- BasicStroke bs = new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
- Line2D line = new Line2D.Double(x,y,x+x1,y+y1);
- g2d.setStroke(bs);
- g2d.draw(line); //绘制直线
- // g2d.setColor(getRandColor(random, 30, 150)); //随机每条线条的颜色
- }
- //输出生成的验证码图片
- g.dispose();
- return image;
- }
- private static Color getRandColor(Random random, int fc, int bc){
- if (fc > 255)
- fc = 255;
- if (bc > 255)
- bc = 255;
- int r = fc + random.nextInt(bc - fc);
- int g = fc + random.nextInt(bc - fc);
- int b = fc + random.nextInt(bc - fc);
- return new Color(r, g, b);
- }
- private static String[] generateCheckCode() {
- String[] res = new String[2];
- Random random = new Random();
- int intTemp;
- int intFirst = random.nextInt(100);
- int intSec = random.nextInt(100);
- String checkCode = "";
- int result = 0;
- switch (random.nextInt(6)) {
- case 0:
- if (intFirst < intSec) {
- intTemp = intFirst;
- intFirst = intSec;
- intSec = intTemp;
- }
- checkCode = intFirst + " - " + intSec + " = ?";
- result = intFirst-intSec;
- break;
- case 1:
- if (intFirst < intSec) {
- intTemp = intFirst;
- intFirst = intSec;
- intSec = intTemp;
- }
- checkCode = intFirst + " - ? = "+(intFirst-intSec);
- result = intSec;
- break;
- case 2:
- if (intFirst < intSec) {
- intTemp = intFirst;
- intFirst = intSec;
- intSec = intTemp;
- }
- checkCode = "? - "+intSec+" = "+(intFirst-intSec);
- result = intFirst;
- break;
- case 3:
- checkCode = intFirst + " + " + intSec + " = ?";
- result = intFirst + intSec;
- break;
- case 4:
- checkCode = intFirst + " + ? ="+(intFirst+intSec);
- result = intSec;
- break;
- case 5:
- checkCode = "? + " + intSec + " ="+(intFirst+intSec);
- result = intFirst;
- break;
- }
- res[0] = checkCode;
- res[1] = String.valueOf(result);
- Constant.LOGGER.info("result=" + result);
- return res;
- }
- @Action("/code/calc")
- public void calcCode() throws IOException{
- int width = 140, height = 37;
- try {
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- Graphics g = image.getGraphics();
- Random random = new Random();
- g.setColor(getRandColor(random, 200, 250));
- g.fillRect(0, 0, width, height);
- String[] fontTypes = { "\u5b8b\u4f53", "\u65b0\u5b8b\u4f53", "\u9ed1\u4f53", "\u6977\u4f53", "\u96b6\u4e66" };
- int fontTypesLength = fontTypes.length;
- g.setColor(getRandColor(random, 160, 200));
- g.setFont(new Font("Times New Roman", Font.PLAIN, 14 + random.nextInt(6)));
- for (int i = 0; i < 255; i++) {
- int x = random.nextInt(width);
- int y = random.nextInt(height);
- int xl = random.nextInt(12);
- int yl = random.nextInt(12);
- g.drawLine(x, y, x + xl, y + yl);
- }
- String[] result = generateCheckCode();
- RedisValidImgCodeUtils.save(request.getSession().getId() + "calc_code", result[1]);
- String [] baseChar = result[0].split(" ");
- for (int i = 0; i < baseChar.length; i++) {
- g.setColor(getRandColor(random, 30, 150));
- g.setFont(new Font(fontTypes[random.nextInt(fontTypesLength)], Font.BOLD, 22 + random.nextInt(6)));
- g.drawString(baseChar[i], 24 * i + 10, 24);
- }
- g.dispose();
- //发送图片
- ResponseUtil.sendImg(response, image, "image/jpeg", "code", "jpg");
- } catch (IllegalStateException e) {
- Constant.LOGGER.error(e.getMessage());
- e.printStackTrace();
- }
- }
- @Action("/code/getRandomCode")
- public void getRandomCode() throws IOException{
- // TODO Auto-generated method stub
- //设置不缓存图片
- response.setHeader("Pragma", "No-cache");
- response.setHeader("Cache-Control", "No-cache");
- response.setDateHeader("Expires", 0);
- //指定生成的响应图片
- response.setContentType("image/jpeg");
- int width=140; //指定生成验证码的宽度
- int height=37; //指定生成验证码的高度
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- Graphics g = image.getGraphics();
- Graphics2D g2d = (Graphics2D)g; //创建Graphics2D对象
- Random random = new Random();
- Font mFont = new Font("黑体", Font.BOLD, 22); //定义字体样式
- g.setColor(getRandColor(200, 250));
- g.fillRect(0, 0, width, height); //绘制背景
- g.setFont(mFont); //设置字体
- g.setColor(getRandColor(180, 200));
- //绘制100根位置和颜色全部为随机产生的线条,该线条为2f
- for (int i = 0; i < 100; i++) {
- int x = random.nextInt(width-1);
- int y = random.nextInt(height-1);
- int x1 = random.nextInt(6)+1;
- int y1 = random.nextInt(12)+1;
- BasicStroke bs = new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
- Line2D line = new Line2D.Double(x,y,x+x1,y+y1);
- g2d.setStroke(bs);
- g2d.draw(line); //绘制直线
- }
- //输出由英文,数字和中文随机组成的验证文字,具体的组合方式根据生成随机数确定
- String sRand = "";
- //输出随机的验证文字
- String ctmp = "";
- int itmp = 0;
- for(int i = 0;i<4;i++){
- switch (random.nextInt(2)) {
- case 0:
- itmp = random.nextInt(26)+65; //生成A~Z的字母
- ctmp = String.valueOf((char)itmp);
- break;
- default:
- ctmp = String.valueOf(random.nextInt(8)+2); //生成2~9的数字
- break;
- }
- sRand+=ctmp;
- Color color = new Color(20+random.nextInt(110), 20+random.nextInt(110), 20+random.nextInt(110));
- g.setColor(color);
- //将生成的随机数进行随机缩放病旋转指定角度
- //将文字旋转指定角度
- Graphics2D g2d_word = (Graphics2D)g;
- AffineTransform trans = new AffineTransform();
- trans.rotate(random.nextInt(45)*3.14/180, 15*i+8, 7);
- //缩放文字
- /*float scaleSize = random.nextFloat()+0.8f;
- if(scaleSize > 1f){
- scaleSize = 1f;
- }
- trans.scale(scaleSize, scaleSize); */
- g2d_word.setTransform(trans);
- g.drawString(ctmp, 20*i+18, 18); //每个字的间距xy
- }
- //将生成的验证码保存道session中
- RedisValidImgCodeUtils.save(request.getSession().getId() + "randCheckCode", sRand);
- //输出生成的验证码图片
- g.dispose();
- ImageIO.write(image, "JPEG", response.getOutputStream());
- }
- public Color getRandColor(int s,int e){
- Random random = new Random();
- if(s>255)s = 255;
- if(e>255)e = 255;
- int r = s+random.nextInt(e-s);
- int g = s+random.nextInt(e-s);
- int b = s+random.nextInt(e-s);
- return new Color(r, g, b);
- }
- public static String getRandomChineseChar() {
- String str = null;
- int hs, ls;
- Random random = new Random();
- hs = (176 + Math.abs(random.nextInt(39)));
- ls = (161 + Math.abs(random.nextInt(93)));
- byte[] b = new byte[2];
- b[0] = (new Integer(hs).byteValue());
- b[1] = (new Integer(ls).byteValue());
- try {
- str = new String(b, "GBk"); //转成中文
- } catch (UnsupportedEncodingException ex) {
- ex.printStackTrace();
- }
- return str;
- }
- }
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
- <script src="${web_url}/api/themes/theme_default/media/js/jquery.js"></script>
- <title>验证码</title>
- </head>
- <body>
- <div style="text-align:center;position:relative;">
- <!--<h2>这是点击的验证码</h2> -->
- <!-- 这是点击的验证码 -->
- <img id="codeT3" src="${web_url}/api/code/getVerificationCode.html?flag=" +Math.random()"/>
- </br>
- <!--
- <input type="button" value="刷新" onclick="getCodeTree();" />
-
- <input type="button" value="校验" onclick="cheakOutTree();" />
- -->
- <select id="codeSelect" style="display: none;"></select>
- <img src="${web_url}/api/refresh.png" style="position:absolute;right:0;top:0; width:20px; height: 20px;" onclick="getCodeTree();" />
- </div>
- <script type="text/javascript">
- //点击次数
- var number=0;
- //获取验证码3
- function getCodeTree() {
- number = 0;
- $(".zhezhao").remove();
- document.getElementById("codeSelect").options.length = 0;
- $("#codeT3").attr("src","${web_url}/api/code/getVerificationCode.html?flag="+Math.random());
- }
- $(function() {
- $("#codeT3").bind("click", function(ev) {
- var oEvent = ev || event;
- //var number = $("#codeSelect option").length;
- number++;
- if (number > 4) {
- return;
- }
- var x = oEvent.pageX;
- var y = oEvent.pageY;
- var img = document.getElementById('codeT3'); //获取图片的原点
- var nodex = getNodePosition(img)[0];//原点x 与原点y
- var nodey = getNodePosition(img)[1];
- var xserver = parseInt(x) - parseInt(nodex);
- var yserver = parseInt(y) - parseInt(nodey);
- $("#codeSelect").append(
- "<option value='"+ (parseInt(number)+1) +"'>" + xserver + "_" + yserver
- + "</option>");
- var oDiv = document.createElement('img');
- oDiv.style.left = (parseInt(x)-15) + 'px'; // 指定创建的DIV在文档中距离左侧的位置 图片大小30 左右移动5
- oDiv.style.top = (parseInt(y) -15) + 'px'; // 指定创建的DIV在文档中距离顶部的位置
- oDiv.style.border = '1px solid #FF0000'; // 设置边框
- oDiv.style.position = 'absolute'; // 为新创建的DIV指定绝对定位
- oDiv.style.width = '30px'; // 指定宽度
- oDiv.style.height = '30px'; // 指定高度
- //oDiv.src = 'select.png';
- oDiv.style.opacity = '0.5'; //透明度
- oDiv.className = 'zhezhao';//加class 点刷新后删除遮罩
- document.body.appendChild(oDiv);
- //第四次点击后自动提交
- if (number == 4) {
- cheakOutTree();
- }
- });
- })
- //校验验证码
- function cheakOutTree() {
- var txt = "";
- $("#codeSelect option").each(function (){
- var text = $(this).text();
- if(txt == ""){
- txt = text;
- }else{
- txt = txt + "," + text;
- }
- });
- $.ajax({
- type:"post",
- url:"${web_url}/api/code/verify.html",
- data : {"code" : txt},
- cache : false,
- success : function(data) {
- alert(data.result);
- if (!data.result) {
- getCodeTree();
- }
- }
- });
- }
- function getNodePosition(node) {
- var top = left = 0;
- while (node) {
- if (node.tagName) {
- top = top + node.offsetTop;
- left = left + node.offsetLeft;
- node = node.offsetParent;
- }
- else {
- node = node.parentNode;
- }
- }
- return [left, top];
- }
- </script>
- </body>
- </html>
java实现点选汉字验证码(自己修改后的)的更多相关文章
- java实现点选汉字验证码(转)
package com.rd.p2p.web; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; im ...
- java实现点选汉字验证码
package com.rd.p2p.web; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; im ...
- 用java将excel表格中的内容修改后写入到另一个excel中
package nn; import java.io.File; import jxl.Cell; import jxl.Sheet; import jxl.Workbook; import jxl. ...
- Java随机生成常用汉字验证码
原文:http://www.open-open.com/code/view/1422514803970 import java.awt.Color; import java.awt.Font; imp ...
- java验证码-汉字验证码
今天整理了一个java实现的汉字输入验证码 主要包含两个类,一个是生成验证码,一个是判断验证码输入是否正确 实现原理非常简单,将汉字和干扰线生成图片并将汉字保存到session,前台获取每次生成验证码 ...
- 字母数字、字母、汉字验证码 (java)
原文:http://blog.csdn.net/qh_java/article/details/49854477 一.字母数字,字母,汉字验证码的生成代码 1.字母数字验证码: package com ...
- PHP算式验证码和汉字验证码的实现方法
在PHP网站开发中,验证码可以有效地保护我们的表单不被恶意提交,但是如果不使用算式验证码或者汉字验证码,仅仅使用简单的字母或者数字验证码,这样的验证码方案真的安全吗? 大家知道简单数字或者字母验证码很 ...
- JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)
JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架) 本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦. 先把实现的发送邮箱验证码更能更新了. 老规矩,更多内容在注释 ...
- Eclipse Java class修改后的即时编译
通常情况下,修改了java文件,需要重启eclipse.但是myeclipse可以不用. 其实即时编译早就有了,通过简单配置javaRebel配置,可以达到修改java文件后不重启eclipse. 注 ...
随机推荐
- perror表
#define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #defi ...
- P4160 [SCOI2009]生日快乐
题目描述 windy的生日到了,为了庆祝生日,他的朋友们帮他买了一个边长分别为 X 和 Y 的矩形蛋糕. 现在包括windy,一共有 N 个人来分这块大蛋糕,要求每个人必须获得相同面积的蛋糕. win ...
- BZOJ1565 [NOI2009]植物大战僵尸 【最大权闭合子图 + tarjan缩点(或拓扑)】
题目 输入格式 输出格式 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. 输入样例 3 2 10 0 20 0 -10 0 -5 1 0 0 100 ...
- C++ primer 学习笔记之容器insert
今天在做练习9.22时,始终出现segments fault.最后才发现原来是自己对“容器insert之后迭代器会失效”的理解不够透彻. 题目如下: 假定iv是一个int的vector,下面的程序存在 ...
- github的使用简易教程
一.安装git https://git-for-windows.github.io/ git -> git bash 二.配置参数 $ git config --global user.na ...
- em,rem
em rem 相对单位: 也可用于设置padding line-height等em相对当前容器的默认字体设置比如,所有浏览器默认字体都是16px,body{ font-size:62.5%}以后即1 ...
- .prm详解
一.内存分配 1.资源分布 如上图所示,单片机型号最后的数字也就代表了单片机中Flash的大小,S12G128 表示Flash有128K Byte,S12G192 表示Flash有192K Byte. ...
- c# tcplistener 与 client通信 服务端 今天写一下
using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Lin ...
- Balanced Lineup(RMQ)
原题传送门 就是裸RMQ啊.. 求区间最大值和区间最小值,一看就像RMQ,当然线段树貌似也可以. 至于算法嘛.自己学~(好吧,放个传送门...) 然后就是最后把maxsum-minsum就好啦233~ ...
- ANDROID开发笔记(二)
动机: 开发的一个背单词的软件. 不会实现划屏的特性. 方法: 第一步尝试: 在MainActivity中, 增加以下代码后, 如果在视图的空白处点击时, 文本框中的时间就会发生改变. @Overri ...