[1.28] T4-C

题目大意

有n个祭坛,每个祭坛有东西南北四个方向

每个祭坛可以选择一个方向发出射线,保证射线不能相交以及射线不能经过其他祭坛

抽象的来说,如果我们以东方向为x轴,北方向为y轴,建立笛卡尔坐标系,那么每个祭坛将会对应一个整点。每个点向上下左右四个方向之一连出一条射线,这些射线不能相交且射线不能经过除了发出点之外的其他点。

求有多少种方法选择每个祭坛的方向,使得祭坛间不发生冲突

题目解析

首先如果一个点往某个方向有另一个点,那么这个点显然不能往这个方向发出射线

我们按照x坐标递增的顺序处理点,发现其实只需要记录4个东西就可以DP了

1、往上的点的y坐标最小值
2、往下的点的y坐标最大值
3、往右的点的y坐标最大值
4、往右的点的y坐标最小值

转移很容易实现,注意如果DP值本身为0就不用转移

代码

#include<bits/stdc++.h>
#define N 60
#define M 998244353 
using namespace std;
struct A 
{
	int x,y;
}e[N];
int n,flag,x,y,ans,f[2][N][N][N][N];
bool cmp(A a,A b)
{ 
	return a.x==b.x?a.y<b.y:a.x<b.x;
}
int min(int x,int y) 
{ 
    if(!x) return y;
	if(!y) return x;
    return e[x].y<e[y].y?x:y; 
}
int max(int x,int y) 
{ 
    if(!x) return y;
	if(!y) return x;
    return e[x].y>e[y].y?x:y; 
}
bool check(int x,int y,int k)
{
    if (y==1&&e[k].x==e[x].x&&e[k].y>e[x].y) return 0;
    if (y==2&&e[k].x==e[x].x&&e[k].y<e[x].y) return 0;
    if (y==3&&e[k].y==e[x].y&&e[k].x<e[x].x) return 0;
    if (y==4&&e[k].y==e[x].y&&e[k].x>e[x].x) return 0;
    return 1;
}
int main()
{
    cin>>n;
    for (int i=1;i<=n;i++)
     cin>>e[i].x>>e[i].y;
    sort(e+1,e+n+1,cmp);
	f[0][0][0][0][0]=y=1,x=0;
    for(int i=1;i<=n;i++)
    {
      for (int j=1;j<=4;j++) 
      {
        flag=0;
        for(int k=1;k<=n;k++)
		 if(!check(i,j,k)) 
		 {
		   flag=1;
		   break;
		 }
         if(!flag)
          for(int u=0;u<i;u++)
           for(int d=0;d<i;d++)
            for(int l=0;l<i;l++)    
             for(int r=0;r<i;r++)
              if(f[x][u][d][l][r])
              {
                if(j==1&&(e[u].y<e[i].y||!u)) (f[y][u][d][min(i,l)][r]+=f[x][u][d][l][r])%=M;
                if(j==2&&(e[d].y>e[i].y||!d)) (f[y][u][d][l][max(r,i)]+=f[x][u][d][l][r])%=M;
                if(j==3&&((e[l].y>e[i].y&&e[r].y<e[i].y)||(!l&&!r)||(e[l].y>e[i].y&&!r)||(e[r].y<e[i].y&&!l))) (f[y][u][d][l][r]+=f[x][u][d][l][r])%=M;
                if(j==4) (f[y][max(i,u)][min(i,d)][l][r]+=f[x][u][d][l][r])%=M;
              }
     }
     x^=1,y^=1;
	 memset(f[y],0,sizeof(f[y]));
    }
    for(int u=0;u<=n;u++)
     for(int d=0;d<=n;d++)
      for(int l=0;l<=n;l++)
       for(int r=0;r<=n;r++)
        (ans+=f[x][u][d][l][r])%=M;
    cout<<ans;
}
``` def get_5_workdays_back(end_date=None): """计算从结束日期倒推5个工作日的起始日期""" end_date = pd.Timestamp.now().normalize() if end_date is None else end_date count = 0 current_date = end_date # 复用原有节假日配置 holidays = [ # 元旦(不调休) '2025-01-01', # 周三 # 春节(调休2天) '2025-01-28', '2025-01-29', '2025-01-30', '2025-01-31', '2025-02-01', '2025-02-02', '2025-02-03', '2025-02-04', # 1.28(除夕)-2.4 # 清明节(不调休) '2025-04-04', '2025-04-05', '2025-04-06', # 周五-周日 # 劳动节(调休1天) '2025-05-01', '2025-05-02', '2025-05-03', '2025-05-04', '2025-05-05', # 周四-周一 # 端午节(不调休) '2025-05-31', '2025-06-01', '2025-06-02', # 周六-周一 # 中秋节+国庆节(调休2天) '2025-10-01', '2025-10-02', '2025-10-03', '2025-10-04', '2025-10-05', '2025-10-06', '2025-10-07', '2025-10-08' # 周三-下周三 ] holiday_dates = pd.to_datetime(holidays) # 新增调休工作日列表(转换为日期格式) workdays_adjustment = [ '2025-01-26', # 周日补春节 '2025-02-08', # 周六补春节 '2025-04-27', # 周日补劳动节 '2025-09-28', # 周日补国庆 '2025-10-11' # 周六补国庆 ] adjustment_dates = pd.to_datetime(workdays_adjustment) # 转换日期格式 while count < 5: current_date -= pd.Timedelta(days=1) # 判断是否为有效工作日 is_workday = ( (current_date.weekday() < 5 or current_date in adjustment_dates) and current_date not in holiday_dates ) if is_workday: count += 1 return current_date, end_date # 获取处理后的数据 df = getchaoshi() # 计算时间范围 start_date, end_date = get_5_workdays_back() date_mask = (df['收案时间'] >= start_date) & (df['收案时间'] <= end_date) weekly_cases = df[date_mask].copy() # 计算上周时间范围 last_week_start, _ = get_5_workdays_back(start_date) date_mask_last_week = (df['收案时间'] >= last_week_start) & (df['收案时间'] < start_date) last_weekly_cases = df[date_mask_last_week].copy() # 分组统计上周数据 last_week_stats = last_weekly_cases.groupby('组别')['案件状态'].count().reset_index() last_week_stats.columns = ['组别', '上周总案件数'] # 新增:统计上周已完成案件(根据结案时间) date_mask_last_week_closed = (df['结案时间'] >= last_week_start) & (df['结案时间'] < start_date) last_week_closed_cases = df[date_mask_last_week_closed].copy() # 分组统计上周已完成数据 last_week_closed_stats = last_week_closed_cases.groupby('组别')['案件状态'].count().reset_index() last_week_closed_stats.columns = ['组别', '上周已完成情况'] # 添加状态分类列 weekly_cases['状态分类'] = weekly_cases['案件状态'].apply( lambda x: '已完成' if x in ['办结', '发件'] else '正在处理' ) # 分组统计 result = weekly_cases.groupby('组别').agg( 总案件数=('案件状态', 'count'), 已完成=('状态分类', lambda x: (x == '已完成').sum()), 处理中=('状态分类', lambda x: (x == '正在处理').sum()), 超时案件数=('是否超时', lambda x: (x == '是').sum()), 缓办案件数=('是否缓办', lambda x: (x == '是').sum()) # 新增行 ).reset_index() # # 合并上周数据 # result = result.merge(last_week_stats, on='组别', how='left').fillna(0) # 合并三组数据(原代码基础上增加新列) result = result.merge(last_week_stats, on='组别', how='left') result = result.merge(last_week_closed_stats, on='组别', how='left').fillna(0) # 新增:添加总计行(核心修改点) total_row = { '组别': '总计', '总案件数': result['总案件数'].sum(), '已完成': result['已完成'].sum(), '处理中': result['处理中'].sum(), '超时案件数': result['超时案件数'].sum(), '缓办案件数': result['缓办案件数'].sum(), '上周总案件数': result['上周总案件数'].sum(), '上周已完成情况': result['上周已完成情况'].sum() # 新增列 } result = pd.concat([result, pd.DataFrame([total_row])], ignore_index=True) # 结果展示样例 print(result.to_markdown(index=False)) # 创建Excel写入对象(注意:需要安装openpyxl) with ExcelWriter('GCB案件统计结果t4.xlsx', engine='openpyxl') as writer: # 将result写入Sheet1 result.to_excel(writer, sheet_name='按周统计情况', index=False) # 将原始数据写入Sheet2 weekly_cases.to_excel(writer, sheet_name='本周案件', index=False) # 将原始数据写入Sheet3 df.to_excel(writer, sheet_name='所有案件', index=False)```输出按周统计情况的表中,增加一列“查询时间”到第一列,输出程序运行的时间,并合并第一列下面的6行,均显示这个时间
03-29
一、综合实战—使用极轴追踪方式绘制信号灯 实战目标:利用对象捕捉追踪和极轴追踪功能创建信号灯图形 技术要点:结合两种追踪方式实现精确绘图,适用于工程制图中需要精确定位的场景 1. 切换至AutoCAD 操作步骤: 启动AutoCAD 2016软件 打开随书光盘中的素材文件 确认工作空间为"草图与注释"模式 2. 绘图设置 1)草图设置对话框 打开方式:通过"工具→绘图设置"菜单命令 功能定位:该对话框包含捕捉、追踪等核心绘图辅助功能设置 2)对象捕捉设置 关键配置: 启用对象捕捉(F3快捷键) 启用对象捕捉追踪(F11快捷键) 勾选端点、中心、圆心、象限点等常用捕捉模式 追踪原理:命令执行时悬停光标可显示追踪矢量,再次悬停可停止追踪 3)极轴追踪设置 参数设置: 启用极轴追踪功能 设置角度增量为45度 确认后退出对话框 3. 绘制信号灯 1)绘制圆形 执行命令:"绘图→圆→圆心、半径"命令 绘制过程: 使用对象捕捉追踪定位矩形中心作为圆心 输入半径值30并按Enter确认 通过象限点捕捉确保圆形位置准确 2)绘制直线 操作要点: 选择"绘图→直线"命令 捕捉矩形上边中点作为起点 捕捉圆的上象限点作为终点 按Enter结束当前直线命令 重复技巧: 按Enter可重复最近使用的直线命令 通过圆心捕捉和极轴追踪绘制放射状直线 最终形成完整的信号灯指示图案 3)完成绘制 验证要点: 检查所有直线是否准确连接圆心和象限点 确认极轴追踪的45度增量是否体现 保存绘图文件(快捷键Ctrl+S)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值