Color

http://poj.org/problem?id=2154

题意:经典polya题

解析:差别就是项链数目不定,采用欧拉函数,求出所有情况求解即可

// File Name: poj2154.cpp
// Author: bo_jwolf
// Created Time: 2013年10月08日 星期二 17:46:30

#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<sstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<ctime>

using namespace std;

int Case;
typedef long long INT;

int eular( int n ){
	int i = 0;
	int ans = 1;
	for( int i = 2; i * i <= n; ++i ){
		if( n % i == 0 ){
			ans *= ( i - 1 );
			n /= i;
			while( n % i == 0 ){
				ans *= i;
				n /= i;
			}
		}
	}
	if( n > 1 )
		ans *= n - 1;
	return ans;
}

INT power( long long a, int b, int p ){
	INT ans = 1, temp = a;
	while( b ){
		if( b & 1 ){
			ans = ( ans * a )% p;
		}
		b >>= 1;
		a = ( a * a )% p;
        }
	return ans;
}

INT calc( int n, int p ){
	INT ans = 0;
	for( int i = 1; i * i <= n; ++i ){
		if( n % i == 0 ){
			ans = ( ans + eular( i ) * power( n , n / i - 1, p ) ) % p;
			if( i * i != n )
				ans = ( ans + eular( n / i ) * power( n, i - 1, p ) ) % p;
		}
	}
	return ans;
}

int main(){
	scanf( "%d", &Case );
	int i, n, p;
	for( int i = 1; i <= Case; ++i ){
		scanf( "%d%d", &n, &p );
		printf( "%I64d\n", calc( n, p ) );
	}

return 0;
}


class EnhancedColorDetector: """增强版颜色检测器,支持精确颜色匹配和调试""" def __init__(self, tolerance=30): # 核心属性初始化 self.tolerance = tolerance self.logger = logging.getLogger('EnhancedCellColorDetector') # 颜色定义(包含所有已知颜色) self.known_colors = { "猩红": "E54C5E", "巧克力黄": "F8CBAD", "钢蓝": "B4C6E7", "无填充": None } # 颜色匹配优先级(修复缺失属性) self.color_priority = [ ("猩红", "E54C5E"), ("巧克力黄", "F8CBAD"), ("钢蓝", "B4C6E7") ] # 统计属性 self.color_stats = defaultdict(int) self.color_matches = defaultdict(int) self.color_mismatches = defaultdict(int) # 缓存属性 self.color_cache = {} self.per_cell_cache = {} def reset_for_new_file(self): """为处理新文件重置状态""" self.color_stats.clear() self.color_matches.clear() self.color_mismatches.clear() self.color_cache.clear() self.logger.info("颜色检测器已重置,准备处理新文件") self.per_cell_cache.clear() def hex_to_rgb(self, hex_color): """将十六进制颜色转换为RGB元组,支持多种格式""" try: if not hex_color: return (0, 0, 0) hex_str = str(hex_color).strip().upper().replace("#", "") # 检查缓存 if hex_str in self.color_cache: return self.color_cache[hex_str] # 处理带Alpha通道的颜色 if len(hex_str) == 8: # 提取Alpha值 alpha = int(hex_str[0:2], 16) / 255.0 # 提取RGB分量 r = int(hex_str[2:4], 16) g = int(hex_str[4:6], 16) b = int(hex_str[6:8], 16) # 混合白色背景 (255,255,255) # 使用更精确的混合算法 r = int(r * alpha + 255 * (1 - alpha) + 0.5) g = int(g * alpha + 255 * (1 - alpha) + 0.5) b = int(b * alpha + 255 * (1 - alpha) + 0.5) result = (r, g, b) self.color_cache[hex_str] = result return result # 处理标准6位HEX if len(hex_str) == 6: result = ( int(hex_str[0:2], 16), int(hex_str[2:4], 16), int(hex_str[4:6], 16) ) self.color_cache[hex_str] = result return result # 处理3位简写HEX if len(hex_str) == 3: result = ( int(hex_str[0]*2, 16), int(hex_str[1]*2, 16), int(hex_str[2]*2, 16) ) self.color_cache[hex_str] = result return result return (0, 0, 0) except Exception as e: self.logger.error(f"颜色转换失败: {hex_color} - {str(e)}") return (0, 0, 0) def rgb_to_hex(self, rgb): """RGB元组转换为HEX字符串""" if not rgb or len(rgb) != 3: return None return f"{rgb[0]:02X}{rgb[1]:02X}{rgb[2]:02X}" def color_distance(self, color1, color2): """ 计算两个颜色之间的感知距离(改进的CIE94公式) 参考: https://en.wikipedia.org/wiki/Color_difference """ if not color1 or not color2: return float('inf') # 无穷大表示完全不匹配 # 使用缓存提高性能 cache_key = f"{color1}_{color2}" if cache_key in self.color_cache: return self.color_cache[cache_key] # 转换为RGB r1, g1, b1 = self.hex_to_rgb(color1) r2, g2, b2 = self.hex_to_rgb(color2) # 转换为Lab颜色空间(更符合人眼感知) lab1 = self.rgb_to_lab((r1, g1, b1)) lab2 = self.rgb_to_lab((r2, g2, b2)) # 计算CIE94颜色差异 L1, a1, b1 = lab1 L2, a2, b2 = lab2 delta_L = L1 - L2 delta_a = a1 - a2 delta_b = b1 - b2 c1 = math.sqrt(a1*a1 + b1*b1) c2 = math.sqrt(a2*a2 + b2*b2) delta_c = c1 - c2 delta_h = math.sqrt(max(delta_a*delta_a + delta_b*delta_b - delta_c*delta_c, 0)) sl = 1.0 kc = 1.0 kh = 1.0 sc = 1.0 + 0.045 * c1 sh = 1.0 + 0.015 * c1 distance = math.sqrt( (delta_L/(sl))**2 + (delta_c/(sc*kc))**2 + (delta_h/(sh*kh))**2 ) self.color_cache[cache_key] = distance return distance def rgb_to_lab(self, rgb): """将RGB颜色转换为Lab颜色空间""" # 先将RGB转换为XYZ r, g, b = [x / 255.0 for x in rgb] # 伽马校正 r = self.gamma_correction(r) g = self.gamma_correction(g) b = self.gamma_correction(b) # 转换为XYZ x = r * 0.4124564 + g * 0.3575761 + b * 0.1804375 y = r * 0.2126729 + g * 0.7151522 + b * 0.0721750 z = r * 0.0193339 + g * 0.1191920 + b * 0.9503041 # D65白点参考值 ref_x = 95.047 ref_y = 100.000 ref_z = 108.883 # 标准化 x = x / ref_x y = y / ref_y z = z / ref_z # 转换为Lab x = self.lab_transform(x) y = self.lab_transform(y) z = self.lab_transform(z) L = max(0, 116 * y - 16) a = 500 * (x - y) b = 200 * (y - z) return (L, a, b) def gamma_correction(self, value): """伽马校正""" if value > 0.04045: return math.pow((value + 0.055) / 1.055, 2.4) else: return value / 12.92 def lab_transform(self, t): """Lab转换函数""" if t > 0.008856: return math.pow(t, 1/3) else: return (7.787 * t) + (16/116) def is_no_fill(self, cell): """检查单元格是否无填充(增强版)""" try: # 检查单元格是否有填充定义 if not hasattr(cell, 'fill') or not cell.fill: return True # 检查填充类型 if hasattr(cell.fill, 'fill_type') and cell.fill.fill_type is None: return True # 检查特定填充类型 if cell.fill.fill_type == 'none': return True # 检查前景色是否自动(默认) if (hasattr(cell.fill, 'fgColor') and hasattr(cell.fill.fgColor, 'type') and cell.fill.fgColor.type == 'auto'): return True # 检查背景色是否自动(默认) if (hasattr(cell.fill, 'bgColor') and hasattr(cell.fill.bgColor, 'type') and cell.fill.bgColor.type == 'auto'): return True # 检查是否有实际颜色值 if hasattr(cell.fill, 'fgColor') and cell.fill.fgColor.rgb: return False if hasattr(cell.fill, 'bgColor') and cell.fill.bgColor.rgb: return False return True except Exception as e: self.logger.error(f"检查无填充失败: {str(e)}") return True def get_cell_color(self, cell): """获取单元格填充颜色的十六进制表示(增强版)""" try: # 检查是否无填充 if self.is_no_fill(cell): return None color_str = None # 尝试获取前景色 if hasattr(cell.fill, 'fgColor') and cell.fill.fgColor: if hasattr(cell.fill.fgColor, 'rgb') and cell.fill.fgColor.rgb: color_str = str(cell.fill.fgColor.rgb).upper() # 如果前景色无效,尝试获取背景色 if not color_str and hasattr(cell.fill, 'bgColor') and cell.fill.bgColor: if hasattr(cell.fill.bgColor, 'rgb') and cell.fill.bgColor.rgb: color_str = str(cell.fill.bgColor.rgb).upper() self.logger.info(f"获取到背景色: {color_str}") return color_str except Exception as e: self.logger.error(f"获取填充颜色失败: {str(e)}") return None def normalize_color(self, color_str): """规范化颜色字符串 - 优化版(修复Alpha处理)""" if not color_str: return None # 转换为字符串并去除空格和# color_str = str(color_str).strip().upper().replace("#", "") # 修复: 处理带Alpha通道的颜色 (8位HEX) if len(color_str) == 8: # 提取Alpha值 alpha_hex = color_str[:2] rgb_hex = color_str[2:] try: alpha = int(alpha_hex, 16) / 255.0 except ValueError: return rgb_hex # 无法解析透明度,当作不透明处理 # 透明度低于50%当作无填充 if alpha < 0.5: return None # 透明度高于50%时进行混合计算 r = int(rgb_hex[0:2], 16) g = int(rgb_hex[2:4], 16) b = int(rgb_hex[4:6], 16) # 混合白色背景 (更精确的混合算法) r = int(r * alpha + 255 * (1 - alpha)) g = int(g * alpha + 255 * (1 - alpha)) b = int(b * alpha + 255 * (1 - alpha)) return f"{r:02X}{g:02X}{b:02X}" # 4. 其他格式直接返回原值 return color_str def match_color(self, hex_color): """ 匹配颜色名称,返回最接近的已知颜色(修复互斥问题) """ if not hex_color: return "无填充" # 修复: 使用互斥优先级匹配 min_distance = float('inf') closest_name = "其他" for name, target in self.color_priority: distance = self.color_distance(hex_color, target) if distance < min_distance: min_distance = distance closest_name = name # 高置信度匹配直接返回 if distance < 5: # 非常接近 return closest_name return closest_name def is_specific_color(self, cell, target_color, tolerance=None, log_details=False): """ 检查单元格是否为特定颜色,允许容差 :param cell: 单元格对象 :param target_color: 目标颜色HEX :param tolerance: 容差值 :param log_details: 是否记录匹配详情 :return: 是否匹配 """ # 使用单元格坐标作为缓存键 cell_key = f"{cell.coordinate}_{target_color}" if cell_key in self.per_cell_cache: return self.per_cell_cache[cell_key] if tolerance is None: tolerance = self.tolerance # 获取单元格颜色(原始值) raw_cell_color = self.get_cell_color(cell) # 规范化单元格颜色和目标颜色 norm_cell_color = self.normalize_color(raw_cell_color) if raw_cell_color else None norm_target_color = self.normalize_color(target_color) if target_color else None # 统计颜色出现次数 self.color_stats[raw_cell_color] += 1 if not norm_cell_color: if log_details: self.logger.debug(f"无填充单元格") return False if not norm_target_color: if log_details: self.logger.debug(f"未提供目标颜色") return False # 当容差为0时,直接比较规范化后的颜色值 # 修复: 添加互斥检查 matched = False if tolerance == 0: matched = (norm_cell_color == norm_target_color) else: distance = self.color_distance(norm_cell_color, norm_target_color) matched = distance <= tolerance # 修复: 检查是否更接近其他颜色 if matched: closest_name = self.match_color_name(norm_cell_color) if closest_name != next((n for n, c in self.color_priority if c == target_color), ""): matched = False # 虽然匹配当前颜色,但有更接近的颜色 if log_details: self.logger.warning(f"颜色冲突: 目标 {target_color} 匹配,但更接近 {closest_name}") # 缓存结果 self.per_cell_cache[cell_key] = matched # 记录匹配详情 - 使用原始颜色值显示 if log_details: actual_rgb = self.hex_to_rgb(norm_cell_color) target_rgb = self.hex_to_rgb(norm_target_color) closest_name = self.match_color_name(norm_cell_color) log_msg = (f"颜色匹配: 原始 #{raw_cell_color} -> 规范 #{norm_cell_color}({actual_rgb}) vs " f"目标 #{norm_target_color}({target_rgb}) - " f"容差: {tolerance}") if tolerance != 0: log_msg += f", 距离: {distance:.2f} {'≤' if matched else '>'} {tolerance}" if matched: self.logger.debug(log_msg) self.color_matches[target_color] += 1 else: self.logger.warning(log_msg + f" | 最接近: {closest_name}") self.color_mismatches[target_color] += 1 return matched def get_color_stats(self): """获取颜色统计信息""" stats = { "total_cells": sum(self.color_stats.values()), "unique_colors": len(self.color_stats), "color_distribution": dict(self.color_stats), "matches": dict(self.color_matches), "mismatches": dict(self.color_mismatches) } return stats def generate_color_report(self): """生成颜色分析报告""" report = ["颜色分析报告:"] report.append(f"总单元格数: {sum(self.color_stats.values())}") report.append(f"唯一颜色数: {len(self.color_stats)}") report.append(f"颜色匹配容差: {self.tolerance}") if self.color_stats: report.append("\n颜色分布:") for color, count in sorted(self.color_stats.items(), key=lambda x: x[1], reverse=True): if color is None: report.append(f" 无填充: {count}") else: rgb = self.hex_to_rgb(color) closest = self.match_color_name(color) report.append(f" #{color} (RGB: {rgb}) - {count}次 - 分类: {closest}") if self.color_matches: report.append("\n成功匹配:") for color, count in self.color_matches.items(): name = next((k for k, v in self.known_colors.items() if v == color), "未知") report.append(f" {name} (#{color}): {count}次") if self.color_mismatches: report.append("\n匹配失败:") for color, count in self.color_mismatches.items(): name = next((k for k, v in self.known_colors.items() if v == color), "未知") report.append(f" {name} (#{color}): {count}次") # 添加颜色匹配率统计 if self.color_matches or self.color_mismatches: total_matches = sum(self.color_matches.values()) total_mismatches = sum(self.color_mismatches.values()) total_attempts = total_matches + total_mismatches match_rate = (total_matches / total_attempts * 100) if total_attempts > 0 else 0 report.append("\n匹配率统计:") report.append(f"总匹配尝试: {total_attempts}") report.append(f"成功匹配: {total_matches} ({match_rate:.2f}%)") report.append(f"匹配失败: {total_mismatches} ({100 - match_rate:.2f}%)") return "\n".join(report) def add_custom_color(self, name, hex_value): """添加自定义颜色""" if not hex_value or len(hex_value) not in (3, 6, 8): self.logger.warning(f"无效的颜色值: {hex_value}") return False # 规范化颜色值 hex_value = self.normalize_color(hex_value) if not hex_value: return False self.known_colors[name] = hex_value self.logger.info(f"已添加自定义颜色: {name} (#{hex_value})") return True def auto_calibrate_tolerance(self): """自动校准颜色匹配容差""" if not self.color_stats: self.logger.warning("没有足够的颜色数据来自动校准") return # 计算所有颜色与目标颜色的平均距离 distances = [] for color in self.color_stats: if color is None: continue min_dist = float('inf') for target in self.known_colors.values(): if target is None: continue dist = self.color_distance(color, target) if dist < min_dist: min_dist = dist if min_dist < float('inf'): distances.append(min_dist) if not distances: return # 计算平均距离和标准差 avg_dist = sum(distances) / len(distances) std_dev = math.sqrt(sum((d - avg_dist)**2 for d in distances) / len(distances)) # 设置新的容差(平均值 + 1.5倍标准差) new_tolerance = min(100, max(10, avg_dist + 1.5 * std_dev)) self.tolerance = new_tolerance self.logger.info(f"自动校准完成: 新容差 = {new_tolerance:.2f}") return new_tolerance 给出完整的修改后的类,并且我建议固定容差为1
最新发布
08-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值