ZOJ 1088

System Overload

Time Limit: 10 Seconds      Memory Limit: 32768 KB

Recently you must have experienced that when too many people use the BBS simultaneously, the net becomes very, very slow.
To put an end to this problem, the Sysop has developed a contingency scheme for times of peak load to cut off net access for some buildings of the university in a systematic, totally fair manner. Our university buildings were enumerated randomly from 1 to n. XWB is number 1, CaoGuangBiao (CGB) Building is number 2, and so on in a purely random order.
Then a number m would be picked at random, and BBS access would first be cut off in building 1 (clearly the fairest starting point) and then in every mth building after that, wrapping around to 1 after n, and ignoring buildings already cut off. For example, if n=17 and m=5, net access would be cut off to the buildings in the order [1,6,11,16,5,12,2,9,17,10,4,15,14,3,8,13,7]. The problem is that it is clearly fairest to cut off CGB Building last (after all, this is where the best programmers come from), so for a given n, the random number m needs to be carefully chosen so that building 2 is the last building selected.

Your job is to write a program that will read in a number of buildings n and then determine the smallest integer m that will ensure that our CGB Building can surf the net while the rest of the university is cut off.

Input Specification

The input file will contain one or more lines, each line containing one integer n with 3 <= n < 150, representing the number of buildings in the university.
Input is terminated by a value of zero (0) for n.

Output Specification

For each line of the input, print one line containing the integer m fulfilling the requirement specified above.

Sample Input

3
4
5
6
7
8
9
10
11
12
0

Sample Output

2
5
2
4
3
11
2
3
8
16

Source: University of Ulm Local Contest 1996

俺的:

ExpandedBlockStart.gif代码
  1 
  2 #include "targetver.h"
  3 
  4 #include <stdio.h>
  5 #include <tchar.h>
  6 
  7 
  8 
  9 // TODO: 在此处引用程序需要的其他头文件
 10 #include <vector>
 11 #include <list>
 12 #include <string>
 13 #include <iostream>
 14 #include <exception>
 15 #include <stdexcept>
 16 
 17 typedef struct{
 18     int        num;
 19     bool    dele;
 20 }Elem;
 21 
 22 // LabCPP.cpp : 定义控制台应用程序的入口点。
 23 //
 24 
 25 #include "stdafx.h"
 26 
 27 using namespace std;
 28 
 29 bool FTestM(vector<Elem> test,vector<Elem>::size_type m)
 30 {
 31     vector<Elem>::size_type total=test.size();        //记录还有多少元素未被测试
 32     vector<Elem>::size_type count=0;                //计数器
 33     try
 34     {
 35         while(!(count==1 && test.at(1).dele==false && total==1))        //测试m是否为2且未被删除且只剩下一个元素
 36         {
 37             //if(test.at(count).dele==true)        //如果该位置的元素已经被删除
 38             //{
 39             //    count++;                    //计数器 +1
 40             //    continue;                    //循环继续
 41             //}
 42             if(count==1 && total != 1 && total !=test.size())            //如果m为2,但是还有其他的元素未被删除,则说明m值不合适
 43             {
 44                 return false;                //函数返回false
 45             }
 46             if(count==1 && total ==1 && total !=test.size())            //m合适
 47             {
 48                 return true;                //函数返回true
 49             }
 50 
 51             //处理元素
 52             test.at(count).dele=true;        //删除该元素
 53             total--;                        //总数 -1
 54             //count+=m;                        //计数器 +m
 55             ////处理越界问题
 56             //if(count>=test.size())
 57             //{
 58             //    count=count%test.size();
 59             //}
 60 
 61             //使用迭代器处理越界和删除元素的情况
 62             try
 63             {
 64                 vector<Elem>::iterator itr=(test.begin()+count);    //不知道指向的位置,假设为下表为count的位置
 65                 int tempcount=0;
 66                 while(tempcount!=m)
 67                 {
 68                     itr++;                    //迭代器自加操作
 69                     if(itr==test.end())        //超过界限,返回到第一位
 70                         itr=test.begin();
 71                     if((*itr).dele==false)    //如果该元素没被删除
 72                         tempcount++;        //计数器 +1
 73                 }
 74                 count=(*itr).num;
 75             }
 76             catch(exception ex4)
 77             {
 78                 cout<<"ex4 error:"<<ex4.what()<<endl;
 79             }
 80         }
 81         return true;
 82     }
 83     catch(exception ex3)
 84     {
 85         cout<<ex3.what()<<endl;
 86         cout<<"ex3 error"<<endl;
 87     }
 88     //catch(runtime_error rterr)
 89     //{
 90     //    cout<<rterr.what()<<endl;
 91     //}
 92     //catch(range_error rgerr)
 93     //{
 94     //    cout<<rgerr.what()<<endl;
 95     //}
 96 }
 97 
 98 int _tmain(int argc, _TCHAR* argv[])
 99 {
100     int n;        //n:有多少建筑
101     cin>>n;
102 
103 
104     Elem elem;        //初始一个Elem值
105     elem.dele=false;
106     elem.num=0;
107 
108     vector<Elem> test(n,elem);        //创建一个名为test的vector容器,内含n个elem的副本
109     try
110     {
111         for (vector<Elem>::size_type i=0;i != n;i++)    //初始化test容器内的元素
112         {
113             test.at(i).num=i;
114         }
115     }
116     catch(exception ex)
117     {
118         cout<<ex.what()<<endl;
119         cout<<"ex error";
120     }
121 
122     vector<Elem>::size_type m;
123     try
124     {
125         for(m=2;m != 150;m++)    
126             //穷举法测试出m的值
127             //150?不确定
128         {
129             if(FTestM(test,m))    //FTestM()测试m是否合适
130                 break;
131             else
132                 ;
133         }
134     }
135     catch(exception ex2)
136     {
137         cout<<ex2.what()<<endl;
138         cout<<"ex2 error";
139     }
140     //输出m的值
141     std::cout<<"The value of 'm' is :"<<endl;
142     std::cout<<m;
143 
144     system("pause");
145     return 0;
146 }
147 
148 

牛人的:

ExpandedBlockStart.gif代码
 1 #include<iostream>
 2 using namespace std;
 3 
 4 
 5 int m;
 6 int n;
 7 
 8 int check(){//优胜者是CGB,返回1,其他返回0
 9 int r=0;//每轮的胜利者
10 for(int i=2; i<n; i++)
11    r = (r+m)%i;
12 if(r==0)
13    return 1;
14 else return 0;
15 }
16 int main()
17 {
18 
19 while(cin>>&& n!=0)
20 {
21    m=1;
22    while(!check())
23     m++;
24    cout<<m<<endl;
25   
26 }
27 }


哭过之后继续努力,呵呵

 

转载于:https://www.cnblogs.com/woodywu/archive/2010/02/10/1666874.html

### ZOJ 1088 线段树 解题思路 #### 题目概述 ZOJ 1088 是一道涉及动态维护区间的经典问题。通常情况下,这类问题可以通过线段树来高效解决。题目可能涉及到对数组的区间修改以及单点查询或者区间查询。 --- #### 线段树的核心概念 线段树是一种基于分治思想的数据结构,能够快速处理区间上的各种操作,比如求和、最大值/最小值等。其基本原理如下: - **构建阶段**:通过递归方式将原数组划分为多个小区间,并存储在二叉树形式的节点中。 - **更新阶段**:当某一段区间被修改时,仅需沿着对应路径向下更新部分节点即可完成全局调整。 - **查询阶段**:利用懒惰标记(Lazy Propagation),可以在 $O(\log n)$ 时间复杂度内完成任意范围内的计算。 具体到本题,假设我们需要支持以下两种主要功能: 1. 对指定区间 `[L, R]` 执行某种操作(如增加固定数值 `val`); 2. 查询某一位置或特定区间的属性(如总和或其他统计量)。 以下是针对此场景设计的一种通用实现方案: --- #### 实现代码 (Python) ```python class SegmentTree: def __init__(self, size): self.size = size self.tree_sum = [0] * (4 * size) # 存储区间和 self.lazy_add = [0] * (4 * size) # 延迟更新标志 def push_up(self, node): """ 更新父节点 """ self.tree_sum[node] = self.tree_sum[2*node+1] + self.tree_sum[2*node+2] def build_tree(self, node, start, end, array): """ 构建线段树 """ if start == end: # 到达叶节点 self.tree_sum[node] = array[start] return mid = (start + end) // 2 self.build_tree(2*node+1, start, mid, array) self.build_tree(2*node+2, mid+1, end, array) self.push_up(node) def update_range(self, node, start, end, l, r, val): """ 区间更新 [l,r], 加上 val """ if l <= start and end <= r: # 当前区间完全覆盖目标区间 self.tree_sum[node] += (end - start + 1) * val self.lazy_add[node] += val return mid = (start + end) // 2 if self.lazy_add[node]: # 下传延迟标记 self.lazy_add[2*node+1] += self.lazy_add[node] self.lazy_add[2*node+2] += self.lazy_add[node] self.tree_sum[2*node+1] += (mid - start + 1) * self.lazy_add[node] self.tree_sum[2*node+2] += (end - mid) * self.lazy_add[node] self.lazy_add[node] = 0 if l <= mid: self.update_range(2*node+1, start, mid, l, r, val) if r > mid: self.update_range(2*node+2, mid+1, end, l, r, val) self.push_up(node) def query_sum(self, node, start, end, l, r): """ 查询区间[l,r]的和 """ if l <= start and end <= r: # 完全匹配 return self.tree_sum[node] mid = (start + end) // 2 res = 0 if self.lazy_add[node]: self.lazy_add[2*node+1] += self.lazy_add[node] self.lazy_add[2*node+2] += self.lazy_add[node] self.tree_sum[2*node+1] += (mid - start + 1) * self.lazy_add[node] self.tree_sum[2*node+2] += (end - mid) * self.lazy_add[node] self.lazy_add[node] = 0 if l <= mid: res += self.query_sum(2*node+1, start, mid, l, r) if r > mid: res += self.query_sum(2*node+2, mid+1, end, l, r) return res def solve(): import sys input = sys.stdin.read data = input().split() N, Q = int(data[0]), int(data[1]) # 数组大小 和 操作数量 A = list(map(int, data[2:N+2])) # 初始化数组 st = SegmentTree(N) st.build_tree(0, 0, N-1, A) idx = N + 2 results = [] for _ in range(Q): op_type = data[idx]; idx += 1 L, R = map(int, data[idx:idx+2]); idx += 2 if op_type == 'Q': # 查询[L,R]的和 result = st.query_sum(0, 0, N-1, L-1, R-1) results.append(result) elif op_type == 'U': # 修改[L,R]+X X = int(data[idx]); idx += 1 st.update_range(0, 0, N-1, L-1, R-1, X) print("\n".join(map(str, results))) solve() ``` --- #### 关键点解析 1. **初始化与构建**:在线段树创建过程中,需要遍历输入数据并将其映射至对应的叶子节点[^1]。 2. **延迟传播机制**:为了优化性能,在执行批量更新时不立即作用于所有受影响区域,而是记录更改意图并通过后续访问逐步生效[^2]。 3. **时间复杂度分析**:由于每层最多只访问两个子树分支,因此无论是更新还是查询都维持在 $O(\log n)$ 范围内[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值