测试赛F - Dragon Balls(并查集)

F - Dragon Balls
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit   Status

Description

Five hundred years later, the number of dragon balls will increase unexpectedly, so it's too difficult for Monkey King(WuKong) to gather all of the dragon balls together. 

His country has N cities and there are exactly N dragon balls in the world. At first, for the ith dragon ball, the sacred dragon will puts it in the ith city. Through long years, some cities' dragon ball(s) would be transported to other cities. To save physical strength WuKong plans to take Flying Nimbus Cloud, a magical flying cloud to gather dragon balls. 
Every time WuKong will collect the information of one dragon ball, he will ask you the information of that ball. You must tell him which city the ball is located and how many dragon balls are there in that city, you also need to tell him how many times the ball has been transported so far.
 

Input

The first line of the input is a single positive integer T(0 < T <= 100). 
For each case, the first line contains two integers: N and Q (2 < N <= 10000 , 2 < Q <= 10000). 
Each of the following Q lines contains either a fact or a question as the follow format: 
  T A B : All the dragon balls which are in the same city with A have been transported to the city the Bth ball in. You can assume that the two cities are different. 
  Q A : WuKong want to know X (the id of the city Ath ball is in), Y (the count of balls in Xth city) and Z (the tranporting times of the Ath ball). (1 <= A, B <= N)
 

Output

For each test case, output the test case number formated as sample output. Then for each query, output a line with three integers X Y Z saparated by a blank space.
 

Sample Input

     
     
2 3 3 T 1 2 T 3 2 Q 2 3 4 T 1 2 Q 1 T 1 3 Q 1
 

Sample Output

     
     
Case 1: 2 3 0 Case 2: 2 2 1 3 3 2
有n个龙珠,在1到n个城市中,T a b 移动a所在城市的所有龙珠到b所在的城市,Q a 输出a所在的城市,城市的龙珠数量,a移动的次数,并查集问题,一个数组记录每个龙珠移动的次数,一个记录城市龙珠的数量,T a b 代表a移动的次数+1,并且所有指向a所在的城市的龙珠移动次数+1 , b所在的城市龙珠数量加a所在的城市
#include <cstdio>
#include <cstring>
int p[11000] , c[11000] , num[11000] ;
/*int f(int x)
{
    int r , k , l , temp = 0 ;
    r = x ;
    while( r != p[r] )
    {
        r = p[r] ;
        temp++ ;
    }
    k = x ;
    while( k != r )
    {
        l = p[k] ;
        c[k] += ( --temp ) ;
        p[k] = r ;
        k = l ;
    }
    return r ;
}*/
int f(int x)
{
    if(x==p[x])
        return x;
    int t=p[x];
    p[x] = f(p[x]);
    c[x] += c[t];
    return p[x];
}
void add(int u,int v)
{
    u = f(u) ;
    v = f(v) ;
    if(u != v)
    {
        p[u] = v ;
        num[v] += num[u] ;
        num[u] = 0 ;
        c[u]++ ;
    }
}
int main()
{
    int t , tt , i , n , m , a , b ;
    char ch ;
    scanf("%d", &t);
    for(tt = 1 ; tt <= t ; tt++)
    {
        printf("Case %d:\n", tt);
        scanf("%d %d", &n, &m);
        for(i = 1 ; i <= n ; i++)
        {
            p[i] = i ;
            num[i] = 1 ;
        }
        memset(c,0,sizeof(c));

        while(m--)
        {
            scanf("%*c%c", &ch);
            if( ch == 'T' )
            {
                scanf("%d %d", &a, &b);
                add(a,b);
            }
            else
            {
                scanf("%d", &a);
                int k = f(a) ;
                printf("%d %d %d\n", k, num[k] , c[a] );
            }
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,作为AI,我不能直接访问和操作本地文件。但是,我可以提供一些思路和代码示例来帮助你完成这个任务。 首先,让我们简要介绍一下这个项目的功能和技术实现。 ## 功能介绍 这个项目是一个轨道绘制器,它可以让用户通过鼠标拖拽的方式在画布上绘制出多个轨道,并在每个轨道上以不同的速度和方向运动的小球。用户可以通过调整速度和方向的参数,控制小球的行动轨迹。 ## 技术实现 这个项目使用了 HTML、CSS 和 JavaScript 技术,其中 JavaScript 代码使用了 Canvas API 来实现绘图和动画效果。 具体来说,JavaScript 代码主要分为以下几个部分: 1. 获取 DOM 元素 在代码中,我们通过 `document.querySelector()` 和 `document.querySelectorAll()` 方法来获取画布元素、输入框元素和按钮元素等。 ```javascript const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); const inputs = document.querySelectorAll("input[type='range']"); const button = document.querySelector("button"); ``` 2. 定义全局变量 在代码中,我们通过定义一些全局变量来存储画布的宽高、小球的数量、小球的半径、小球的颜色、轨道的半径、轨道的数量等。 ```javascript let canvasWidth, canvasHeight; let numBalls, ballRadius, ballColor; let numOrbits, orbitRadius, orbitColor; ``` 3. 初始化画布 在代码中,我们通过调用 `initCanvas()` 函数来初始化画布的大小,并设置画布的背景色。 ```javascript function initCanvas() { canvasWidth = window.innerWidth; canvasHeight = window.innerHeight; canvas.width = canvasWidth; canvas.height = canvasHeight; ctx.fillStyle = "#000"; ctx.fillRect(0, 0, canvasWidth, canvasHeight); } ``` 4. 定义 Ball 类 在代码中,我们定义了一个 Ball 类来表示每个小球,该类包含了小球的位置、速度、半径、颜色等属性,以及绘制小球和更新小球位置的方法。 ```javascript class Ball { constructor(x, y, vx, vy, r, color) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.r = r; this.color = color; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2); ctx.fillStyle = this.color; ctx.fill(); } update() { this.x += this.vx; this.y += this.vy; } } ``` 5. 定义 Orbit 类 在代码中,我们定义了一个 Orbit 类来表示每个轨道,该类包含了轨道的半径、颜色等属性,以及绘制轨道的方法。 ```javascript class Orbit { constructor(r, color) { this.r = r; this.color = color; } draw() { ctx.beginPath(); ctx.arc(canvasWidth / 2, canvasHeight / 2, this.r, 0, Math.PI * 2); ctx.strokeStyle = this.color; ctx.stroke(); } } ``` 6. 定义全局变量 balls 和 orbits 在代码中,我们定义了两个全局变量 balls 和 orbits,分别用来存储所有小球和所有轨道的实例对象。 ```javascript let balls = []; let orbits = []; ``` 7. 初始化小球和轨道 在代码中,我们通过调用 `initBalls()` 和 `initOrbits()` 函数来初始化小球和轨道,具体实现可以参考代码。 8. 绘制小球和轨道 在代码中,我们通过调用 `drawBalls()` 和 `drawOrbits()` 函数来绘制小球和轨道,具体实现可以参考代码。 9. 更新小球位置 在代码中,我们通过调用 `updateBalls()` 函数来更新小球的位置,具体实现可以参考代码。 10. 绑定事件监听函数 在代码中,我们通过调用 `bindEventListeners()` 函数来绑定事件监听函数,具体实现可以参考代码。 11. 启动动画循环 在代码中,我们通过调用 `requestAnimationFrame()` 方法来启动动画循环,具体实现可以参考代码。 以上就是这个项目的主要代码实现部分,下面我们来看一下如何完成 `04-orbit-draw.html` 文件并注释关键代码。 ### HTML 代码 首先,我们需要在 HTML 文件中创建画布元素、输入框元素和按钮元素等。具体实现可以参考下面的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Orbit Draw</title> <style> body { margin: 0; padding: 0; overflow: hidden; } canvas { display: block; } .controls { position: absolute; top: 0; left: 0; padding: 10px; background-color: rgba(0, 0, 0, 0.5); color: #fff; } </style> </head> <body> <canvas></canvas> <div class="controls"> <p>Number of balls: <input type="range" min="1" max="100" value="10"></p> <p>Ball radius: <input type="range" min="1" max="50" value="10"></p> <p>Ball color: <input type="color" value="#fff"></p> <p>Number of orbits: <input type="range" min="1" max="10" value="3"></p> <p>Orbit radius: <input type="range" min="50" max="200" value="100"></p> <p>Orbit color: <input type="color" value="#fff"></p> <p><button>Reset</button></p> </div> <script src="app.js"></script> </body> </html> ``` ### JavaScript 代码 然后,我们需要在 JavaScript 文件中编写代码来实现上述功能。具体实现可以参考下面的示例代码: ```javascript // 获取 DOM 元素 const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); const inputs = document.querySelectorAll("input[type='range']"); const button = document.querySelector("button"); // 定义全局变量 let canvasWidth, canvasHeight; let numBalls, ballRadius, ballColor; let numOrbits, orbitRadius, orbitColor; // 初始化画布 function initCanvas() { canvasWidth = window.innerWidth; canvasHeight = window.innerHeight; canvas.width = canvasWidth; canvas.height = canvasHeight; ctx.fillStyle = "#000"; ctx.fillRect(0, 0, canvasWidth, canvasHeight); } // 定义 Ball 类 class Ball { constructor(x, y, vx, vy, r, color) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.r = r; this.color = color; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2); ctx.fillStyle = this.color; ctx.fill(); } update() { this.x += this.vx; this.y += this.vy; } } // 定义 Orbit 类 class Orbit { constructor(r, color) { this.r = r; this.color = color; } draw() { ctx.beginPath(); ctx.arc(canvasWidth / 2, canvasHeight / 2, this.r, 0, Math.PI * 2); ctx.strokeStyle = this.color; ctx.stroke(); } } // 定义全局变量 let balls = []; let orbits = []; // 初始化小球 function initBalls() { balls = []; for (let i = 0; i < numBalls; i++) { const angle = Math.random() * Math.PI * 2; const x = canvasWidth / 2 + orbitRadius * Math.cos(angle); const y = canvasHeight / 2 + orbitRadius * Math.sin(angle); const speed = Math.random() * 2 + 1; const vx = speed * Math.cos(angle - Math.PI / 2); const vy = speed * Math.sin(angle - Math.PI / 2); const ball = new Ball(x, y, vx, vy, ballRadius, ballColor); balls.push(ball); } } // 初始化轨道 function initOrbits() { orbits = []; for (let i = 0; i < numOrbits; i++) { const r = orbitRadius * (i + 1) / numOrbits; const orbit = new Orbit(r, orbitColor); orbits.push(orbit); } } // 绘制小球 function drawBalls() { balls.forEach(ball => ball.draw()); } // 绘制轨道 function drawOrbits() { orbits.forEach(orbit => orbit.draw()); } // 更新小球位置 function updateBalls() { balls.forEach(ball => ball.update()); } // 绑定事件监听函数 function bindEventListeners() { window.addEventListener("resize", initCanvas); inputs.forEach(input => { input.addEventListener("change", () => { numBalls = inputs[0].value; ballRadius = inputs[1].value; ballColor = inputs[2].value; numOrbits = inputs[3].value; orbitRadius = inputs[4].value; orbitColor = inputs[5].value; initBalls(); initOrbits(); }); }); button.addEventListener("click", () => { inputs.forEach(input => { input.value = input.getAttribute("value"); }); numBalls = inputs[0].value; ballRadius = inputs[1].value; ballColor = inputs[2].value; numOrbits = inputs[3].value; orbitRadius = inputs[4].value; orbitColor = inputs[5].value; initBalls(); initOrbits(); }); } // 启动动画循环 function animate() { ctx.fillStyle = "rgba(0, 0, 0, 0.1)"; ctx.fillRect(0, 0, canvasWidth, canvasHeight); drawOrbits(); drawBalls(); updateBalls(); requestAnimationFrame(animate); } // 初始化 function init() { numBalls = inputs[0].value; ballRadius = inputs[1].value; ballColor = inputs[2].value; numOrbits = inputs[3].value; orbitRadius = inputs[4].value; orbitColor = inputs[5].value; initCanvas(); initBalls(); initOrbits(); bindEventListeners(); animate(); } init(); ``` 在代码中,我们首先获取了画布元素、输入框元素和按钮元素等,然后定义了一些全局变量来存储画布的宽高、小球的数量、小球的半径、小球的颜色、轨道的半径、轨道的数量等。 接着,我们实现了初始化画布、Ball 类、Orbit 类、小球和轨道的初始化、小球和轨道的绘制、小球位置的更新、事件监听函数的绑定和动画循环启动等功能。 最后,我们在 `init()` 函数中调用这些功能函数,完成了整个项目的实现。 希望这份代码示例能帮助你快速理解和完成 `04-orbit-draw.html` 文件的开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值