今天在学习shiro的时候使用另一种shiro验证的方式。

  总体的思路是:

     (1)先在自己的方法中进行身份的验证以及给出提示信息。(前提是将自己的验证方法设为匿名可访问)

     (2)当验证成功之后到Shiro中认证以及授权一下即可(授权的时候保存用户的权限与角色字符串)。当然,在自己验证成功之后需要向session中存入所需要的数据。

     (3)验证成功之后向前台返回登录成功,此时也已经在shiro中授权,后台可以请求后台地址。如果后台地址不确定的时候需要在验证成功向前台反馈的时候携带一个成功之后的地址。

其大致流程如下:

(1)配置静态资源可以匿名访问
(2)shiro配置loginUrl认证提交地址,login.do。(此方法只是简单的将页面的地址转发到login.jsp)
(3)登录的地址: userLogin.do 处理登录流程的controller
(1)正常登录
(2)登录成功之后进行shiro权限认证
(3)登录失败提示失败信息 Service登录获取登录信息,该用户所有的权限信息,该用户所有的权限码,返回到Controller
controller根据登录信息判断是否进行shiro认证。 如果登录信息是登录成功:
将当前用户对象存到session中,将当前用户的菜单存到session中
前台根据返回的信息判断是否进行页面跳转(登录成功跳转到index.jsp)
如果登录失败:啥都不做

0.数据库中权限表结构:

    menu1表示一级菜单,menu2表示2级菜单,menu3表示3级菜单。

    permissionCode是权限码,在代码或者jsp中可以进行判断。

代码中验证:

        // 获取用户信息
Subject currentUser = SecurityUtils.getSubject();
boolean permitted = currentUser.isPermitted("exammanager:factory");// 判断是否有全厂管理的权限,有就不添加部门ID,没有就设为当前Session中的部门ID
String departmentId = permitted ? null : departmentIdSession;

JSP页面进行验证权限:

<shiro:hasPermission name="department:operating">
<script>
hasOperatingDepart = true;
</script>
</shiro:hasPermission>

1.Shiro配置

  主要是配置一下登录的请求地址:这是一个虚拟的地址,仅仅是为了将首页地址隐藏,

    然后配置一些可以匿名访问的资源,就是不需要登录就可以访问的资源。  ** 两颗星表示任意目录均可以访问,* 表示当前目录的资源可以访问。一般都是两颗 * 。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> <!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
<!-- 记住我 -->
<property name="rememberMeManager" ref="rememberMeManager"/>
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
<!-- 注入session管理器 -->
<property name="sessionManager" ref="sessionManager"/>
</bean> <!-- 自定义Realm进行认证和授权 -->
<bean id="myRealm" class="cn.xm.jwxt.shiro.CustomRealm" /> <!-- 自定义form认证过虑器 -->
<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
<bean id="formAuthenticationFilter"
class="cn.xm.jwxt.shiro.CustomFormAuthenticationFilter">
<property name="usernameParam" value="usercode" />
<property name="passwordParam" value="password" />
<property name="usersort" value="usersort" />
<!--<property name="rememberMeParam" value="rememberMe"/>-->
</bean> <!-- ehcache缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean> <!-- session会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- session失效时间 单位毫秒 -->
<property name="globalSessionTimeout" value="18000000"/>
<!-- 删除失效的session -->
<property name="deleteInvalidSessions" value="true"/>
</bean> <!-- rememberMeManager管理器,写cookie,取出cookie生成用户信息 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cookie" ref="rememberMeCookie" />
</bean> <!-- 会话Cookie模板 -->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="sid"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="-1"/>
</bean> <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="2592000"/><!-- 30天 -->
</bean> <!-- logout -->
<bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
<!-- <property name="redirectUrl" value="/index.jsp" /> -->
<property name="redirectUrl" value="/index.jsp" />
</bean> <!-- web.xml中shiro的filter对应的bean -->
<!-- Shiro 的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.do" />
<!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
<property name="successUrl" value="/index.jsp" />
<!-- 通过unauthorizedUrl指定没有权限操作时跳转页面 -->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 自定义filter配置 -->
<property name="filters">
<map>
<!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中 -->
<entry key="authc" value-ref="formAuthenticationFilter" />
</map>
</property>
<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
<!-- 静态资源放行 -->
/css/** = anon
/fonts/** = anon
/images/** = anon
/js/** = anon
/lib/** = anon
/login.jsp=anon
/userLogin.do=anon <!-- 请求 logout.action地址,shiro去清除session -->
/logout.do = logout <!-- /** = authc 所有url都必须认证通过才可以访问 -->
/** = authc
</value>
</property>
</bean> <!-- 开启Shiro注解 -->
<aop:config proxy-target-class="true"></aop:config>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>

2.User.java  (将来要被保存到session中的实体类)

  包含当前用户的身份信息想,以及当前用户的菜单以及所有的权限。

package cn.xm.jwxt.bean.system;

import java.util.List;
import java.util.Set; public class User {
private String userid;//用户ID private String usercode;//用户code(登录用这个) private String username;//用户姓名 private String password;//用户密码 private String usersort;//用户类型 private String userstuteanum;//用户编号(学号或者教师编号) private String userunitname;//用户所属单位名称(班级名称或者教研室名称) private String userunitnum;//班级编码或者教研室编码 private String isuse;//是否在用 private String remark1;//备注 private List<Permission> permissions;//所有权限 private Set<String> permissionCodes;//所有权限码 private List<Permission> menuPermissions;//所有菜单权限(按序号排列)
  .....

 3.Controller层  login 方法:

    第一个仅仅是转发页面,第二个是真正的处理登录的业务逻辑,登录成功之后再到shiro认证一下即可完成shiro登录。

package cn.xm.jwxt.controller.system;

import cn.xm.jwxt.bean.system.User;
import cn.xm.jwxt.service.system.UserService;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.sql.SQLException;
import java.util.Map; /**
* @Author: qlq
* @Description 登录controller
* @Date: 11:28 2018/5/13
*/
@Controller
public class LoginController {
private final String SESSION_USER_INFO="userinfo"; //用户信息的session名
private final String SESSION_PERMISSION_INFO="permissioninfo"; //权限信息的session名
@Autowired
private UserService userService;//用于处理登录的业务流程
private Logger logger = Logger.getLogger(LoginController.class); // 未登录的用户默认重定向到的地址.和applicationContext-shiro.xml中配置的loginurl一致(只是简单的将地址转发到login.jsp)
@RequestMapping("/login")
public String login() throws Exception {
return "login";
} /**
* @param usercode 账户
* @param password 密码
* @param usersort 用户类型
* @return 登录结果
* @throws Exception
*/
@RequestMapping("/userLogin")
public @ResponseBody Map<String,Object> userLogin(@RequestParam(defaultValue = "1") String usercode, @RequestParam(defaultValue = "1") String password, @RequestParam(defaultValue = "1") String usersort, HttpServletRequest request) {
Map<String, Object> userLoginInfo =null;
try {
userLoginInfo = userService.getUserLoginInfo(usercode, password, usersort);
} catch (SQLException e) {
logger.error("登录出错",e);
userLoginInfo.put("loginInfo","登录失败!");
return userLoginInfo;
}
String loginInfo = (String) userLoginInfo.get("loginInfo");//获取登录信息
////shiro的使用需要先把用户的信息放入session 需要先用shiro的方法进行登录 但是登录方法已经写好。这里在登录成功之后用shiro的方法再登录一次
if("登录成功" == loginInfo){
//1.存session东西
HttpSession session=request.getSession();
User user = (User) userLoginInfo.get("user");
session.setAttribute(SESSION_USER_INFO, user);
session.setAttribute(SESSION_PERMISSION_INFO, user.getPermissions());
userLoginInfo.remove("user");//从map中删除用户返回前台
//2.到shiro验证授权
Subject currentUser=SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(usercode, password);
currentUser.login(token);
}
return userLoginInfo;
}
}

4.Service层登录方法:

  根据用户输入的usercode查询数据库,并依次匹配密码和用户类型

  如果登录之后再提取该用户的所有权限与菜单permission。

    @Override
public Map<String, Object> getUserLoginInfo(String usercode, String password, String usersort) throws SQLException {
Map<String,Object> result= new HashMap<String,Object>();
String loginInfo = null;//登录信息
List<Permission> permissions = null;//所有权限
Set<String> permissionCodes = null;//所有权限码
//1.进行登录(分别根据usercode,password,usersort进行判断)
UserExample userExample = new UserExample();
UserExample.Criteria criteria = userExample.createCriteria();
criteria.andUsercodeEqualTo(usercode);
List<User> users = userMapper.selectByExample(userExample);
//1.1判断账户
if(users == null || users.size()==0){
loginInfo = "账户不存在!";
result.put("loginInfo",loginInfo);
return result;
}
User user = users.get(0);
//1.2判断密码
String password_sql = user.getPassword();
if(password_sql == null || !password_sql.equals(password)){
loginInfo = "密码错误!";
result.put("loginInfo",loginInfo);
return result;
}
//1.3 判断类型
String usersort_sql = user.getUsersort();
if(usersort_sql == null || !usersort_sql.equals(usersort)){
loginInfo = "账户类型错误!";
result.put("loginInfo",loginInfo);
return result;
}
//1.4判断账户状态
String userStatus_sql = user.getIsuse();
if(userStatus_sql == null || userStatus_sql.equals("0")){
loginInfo = "账户已锁定,请联系管理员开启账户!";
result.put("loginInfo",loginInfo);
return result;
}
//2.查询该用户的所有的权限List<Permission> permissions
permissions = this.selectPermissionsByUserId(user.getUserid());
if(permissions == null || permissions.size() == 0){
loginInfo = "该账户还没有任何权限,请联系管理员分配权限!";
result.put("loginInfo",loginInfo);
return result;
}
//3.提取该用户的所有的权限码Set<String> permissionCodes
permissionCodes = new HashSet<>();
for(Permission permission:permissions){
if(ValidateCheck.isNotNull(permission.getPermissioncode())){
permissionCodes.add(permission.getPermissioncode());
}
}
//4.提取该用户所有的菜单:
Map condition = new HashMap();
condition.put("userId",user.getUserid());
condition.put("menu","1");
List<Permission> menus = this.getUserPermissionsByCondition(condition);
//5.将登录信息设为登录成功
loginInfo = "登录成功";
result.put("loginInfo",loginInfo);
user.setPermissions(permissions);//所有权限
user.setPermissionCodes(permissionCodes);//所有权限码
user.setMenuPermissions(menus);//所有菜单权限
result.put("user",user);
return result;
}

 5.Shiro的权限认证和授权:(自定义realm进行认证和授权)

  认证:如果认证通过,返回一个  SimpleAuthenticationInfo 对象,认证失败返回 null

  授权: 根据 userId 查询该用户的所有权限码(permissionCode) ,以字符串集合的形式添加(可以是set,也可以是list的形式)。以字符串的形式添加角色信息(Set<roleName>的形式)

package cn.xm.jwxt.shiro;

import cn.xm.jwxt.bean.system.Permission;
import cn.xm.jwxt.bean.system.User;
import cn.xm.jwxt.service.system.UserService;
import cn.xm.jwxt.utils.ValidateCheck;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired; import java.util.HashSet;
import java.util.List;
import java.util.Set; /**
* @Author: qlq
* @Description 自定义realm。根据上面传下来的token去数据库查信息,查到返回一个SimpleAuthenticationInfo,查不到返回null(用于shiro认证)
* @Date: 21:56 2018/5/6
*/
public class CustomRealm extends AuthorizingRealm { @Autowired
private UserService userService; // 设置realm的名称
@Override
public void setName(String name) {
super.setName("customRealm");
} // realm的认证方法,从数据库查询用户信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userCode=(String)token.getPrincipal();//获取token的主身份(登录的username
User user = null;
try {
user = userService.getUserByUserCode(userCode);
} catch (Exception e) {
e.printStackTrace();
}
AuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
return authenticationInfo;
}
// 用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//0.下面方法principals.getPrimaryPrincipal()获取的是在上面认证的时候装进AuthenticationInfo的对象
String userId=((User)(principals.getPrimaryPrincipal())).getUserid();
SimpleAuthorizationInfo simpleAuthorizationInfo=null;
try {
simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//1.设置所有的权限(注意权限是以字符串的形式保存的权限码)
List<Permission> permissions1 = userService.selectPermissionsByUserId(userId);//获取所有权限码
Set<String> permissions = new HashSet<>();
for(Permission permission:permissions1){
if(ValidateCheck.isNotNull(permission.getPermissioncode())){
permissions.add(permission.getPermissioncode());
}
}
if (permissions != null && permissions.size()>0) {
simpleAuthorizationInfo.setStringPermissions(permissions);
}
//2.设置角色,角色也是以字符串的形式表示(这里存的是角色名字)
Set<String> userRoleNames = userService.getUserRoleNameByUserId(userId);
if(userRoleNames != null && userRoleNames.size()>0){
simpleAuthorizationInfo.setRoles(userRoleNames);
}
} catch (Exception e) {
e.printStackTrace();
}
return simpleAuthorizationInfo;
} // 清除缓存
public void clearCached() {
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
super.clearCache(principals);
} }

注意:  (principals.getPrimaryPrincipal())).getUserid(); 是在认证的时候返回 AuthenticationInfo 对象的第一个参数。

 6.前端登录方法:

  如果返回的不是登录成功就是登录失败了,就弹出失败信息。否则就是登录成功,登录成功之后访问我后台首页。此时也已经完成shiro认证,可以访问后台。

    //1.监听登录表单的提交
form.on('submit(login)', function(data){
$.ajax({
url:contextPath+'/userLogin.do',
type:"post",
async:false,
data:$("#loginForm").serialize(),
success:function (response) {
if(response != null && response.loginInfo != "登录成功"){
layer.msg(response.loginInfo,{time:2*1000,icon:2,shade: [0.8, '#393D49']});
}else{
window.location.href=contextPath;//登录成功跳转到首页
}
},
dataType:'json'});
});

7.前端首页根据session中的用户的菜单显示对应的菜单:

<div class="left-nav">
<div id="side-nav">
<ul id="nav">
<!--遍历一级菜单-->
<c:forEach var="menu1" items="${userinfo.menuPermissions}">
<c:if test="${menu1.permissiontype=='menu1' }">
<li>
<a href=javascript:void(0)>
<cite>${menu1.permissionname}</cite>
<i class="iconfont nav_right"></i>
</a>
<ul class="sub-menu">
<!--遍历二级菜单-->
<c:forEach var="menu2" items="${userinfo.menuPermissions}">
<c:if test="${menu2.permissiontype=='menu2' and menu2.parentid == menu1.permissionid}">
<!--如果url不为空就是二级菜单-->
<c:if test="${menu2.url != '' && menu2.url != null}">
<li>
<a _href="${menu2.url}">
<cite>${menu2.permissionname}</cite>
</a>
</li>
</c:if>
<!--如果url为空就是三级菜单-->
<c:if test="${menu2.url == null || menu2.url == ''}">
<li>
<a href="javascript:;">
<cite>${menu2.permissionname}</cite>
<i class="iconfont nav_right"></i>
</a>
<ul class="sub-menu">
<%--遍历获取三级菜单--%>
<c:forEach var="menu3" items="${userinfo.menuPermissions}">
<c:if test="${menu3.permissiontype=='menu3' and menu3.parentid == menu2.permissionid}">
<li>
<a _href="${menu3.url}">
<cite>${menu3.permissionname}</cite>
</a>
</li>
</c:if>
</c:forEach>
</ul>
</li>
</c:if>
</c:if>
</c:forEach>
</ul>
</li>
</c:if>
</c:forEach>
</ul>
</div>
</div>

8.前端退出系统的操作:

<script>
/**
* 退出系统相关操作
*/
function logoutSystem(){
layui.use(['layer'],function () {
var layer = layui.layer;
layer.confirm("确认退出系统?",{icon:3,shade: [0.8, '#393D49']},function () {
window.location.href=contextPath+"/logout.do";
})
})
}
</script>

后端只用在shiro配置文件中配置一下  /logout.do=logout  当访问这个路径的时候shiro会自动清除session中的东西。

                <!-- 请求 logout.action地址,shiro去清除session -->
/logout.do = logout

Shiro认证的另一种方式的更多相关文章

  1. Spring Boot 整合 Shiro ,两种方式全总结!

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  2. Shiro源代码分析之两种Session的方式

    1.Shiro默认的Session处理方式 <!-- 定义 Shiro 主要业务对象 --> <bean id="securityManager" class=& ...

  3. 在Spring-Boot中实现通用Auth认证的几种方式

    code[class*="language-"], pre[class*="language-"] { background-color: #fdfdfd; - ...

  4. Apache Shiro 使用手册(二)Shiro 认证

    认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的"实体/凭证"组合便是&quo ...

  5. Apache Shiro 认证过程

    3.1.1    示例 Shiro验证Subjects 的过程中,可以分解成三个不同的步骤: 1. 收集Subjects 提交的Principals(身份)和Credentials(凭证): 2. 提 ...

  6. 【shiro】(4)---Shiro认证、授权案例讲解

    Shiro认证.授权案例讲解 一.认证  1. 认证流程     2.用户密码已经加密.加盐的用户认证 (1)测试类 // 用户登陆和退出,这里我自定了一个realm(开发肯定需要自定义realm获取 ...

  7. shiro源码篇 - shiro认证与授权,你值得拥有

    前言 开心一刻 我和儿子有个共同的心愿,出国旅游.昨天儿子考试得了全班第一,我跟媳妇合计着带他出国见见世面,吃晚饭的时候,一家人开始了讨论这个.我:“儿子,你的心愿是什么?”,儿子:“吃汉堡包”,我: ...

  8. 将 Shiro 作为应用的权限基础 二:shiro 认证

    认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的“实体/凭证”组合便是“用户名/密码”组合. 一. ...

  9. Apache Shiro 使用手册(二)Shiro 认证(转发:http://kdboy.iteye.com/blog/1154652)

    认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的“实体/凭证”组合便是“用户名/密码”组合. 一. ...

随机推荐

  1. jQuery文件上传插件uploadify

    官方网站:http://www.uploadify.com/ 参考博客:jQuery Uploadify在ASP.NET MVC3中的使用 参考博客:使用uploadify上传图片时返回“Cannot ...

  2. P4867 Gty的二逼妹子序列

    题目描述 Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数. 为了方便,我们规定妹子们的美 ...

  3. Day22-Django之信号

    1. 如果往数据库中增加数据的时候,希望生成一个日志.在数据保存之前以及保存之后. Django中提供了“信号调度”,用于在框架执行操作时解耦.通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去 ...

  4. 超计算(Hyper computation)模型

    超计算(Hyper computation)模型 作者:Xyan Xcllet链接:https://www.zhihu.com/question/21579465/answer/106995708来源 ...

  5. Virtual Table

    C++对象模型——吴泰 C/C++杂记 C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现 C++ 多继承和虚继承的内存布局 [已翻译100%] (虚继承参考,推荐) 图说C++对象模型:对 ...

  6. [Ispc2009]Let there be rainbows!

    Description HY Star是一个处处充满和谐,人民安居乐业的星球,但是HYStar却没有被评上宇宙文明星球,很大程度上是因为星球的形象问题. HY Star由N个国家组成,并且在一些国家之 ...

  7. 【刷题】BZOJ 4816 [Sdoi2017]数字表格

    Description Doris刚刚学习了fibonacci数列.用f[i]表示数列的第i项,那么 f[0]=0 f[1]=1 f[n]=f[n-1]+f[n-2],n>=2 Doris用老师 ...

  8. Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)

    Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列) Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺 ...

  9. 【loj2586】【APIO2018】选圆圈

    题目 有 \(n\) 个圆$c_1,c_2, \cdots , c_n $,执行如下的操作: 找到剩下的半径最大的圆删除并删除所有和它有交的其他并没有被删除的圆: 求每个圆是被那个圆删除的: $1 \ ...

  10. python学习(22) 访问数据库

    原文链接:http://www.limerence2017.com/2018/01/11/python22/ 本文介绍python如何使用数据库方面的知识. SQLite SQLite是一种嵌入式数据 ...