J - Quick Estimates

本文介绍了一种帮助工人快速估算家庭维修成本规模的程序设计方案。该方案旨在解决初次访问时成本预估过高或过低的问题,通过计算成本的位数来提供一个大致的成本范围。

Let’s face it… you are not that handy. When you need to make a major home repair, you often need to hire someone to help. When they come for the first visit, they make an estimate of the cost. Here they must be careful: if they overestimate the cost, it might scare you off, but if they underestimate, the work might not be worth their time.

Because the worker is so careful, it can take a long time for them to produce the estimate. But that’s frustrating — when you ask for an estimate, you really are asking for the magnitude of the cost. Will this be $10
or $100 or $1000

? That’s all you really want to know on a first visit.

Please help the worker make the type of estimate you desire. Write a program that, given the worker’s estimate, reports just the magnitude of the cost — the number of digits needed to represent the estimate.
Input

Input begins with a line containing an integer N
(1≤N≤100). The next N lines each contain one estimated cost, which is an integer between 0 and 10100

. (Some of the workers overcharge quite a bit.)
Output

For each estimated cost, output the number of digits required to represent it.

#include <bits/stdc++.h>
using namespace std;
const int maxn=110;
const int inf=0x3f3f3f3f;
int n;
int val[maxn];
int mapp[maxn][maxn];
int dis[maxn],ans[maxn];
bool vis[maxn];
void dij()
{
    for(int i=1; i<=n; i++)
        dis[i]=mapp[1][i];
    dis[1]=0;
    int minn,V=-1,k;
    for (int i = 1; i <=n ; ++i)
    {
        minn=inf;
        k=V;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j]&&minn>dis[j])
            {
                minn=dis[j];
                V=j;
            }

        }
        vis[V]=true;
        for (int j = 1; j <=n ; ++j)
        {
            if(!vis[j]&&dis[j]>dis[V]+mapp[V][j])
            {
                dis[j]=dis[V]+ mapp[V][j];
                ans[j]=ans[V]+val[j];
            }
            else if(!vis[j]&&dis[j]==dis[V]+mapp[V][j])
            {
                ans[j]=max(ans[j],ans[V]+val[j]);
            }
        }
    }

    if(dis[n]==inf)
        printf("impossible\n");
    else
        printf("%d %d\n",dis[n],ans[n]+val[1]);
}
int main()
{
    scanf("%d",&n);
    memset(mapp,0x3f, sizeof(mapp));
    for (int i =1; i <=n ; ++i)
    {
        scanf("%d",&val[i]);
        mapp[i][i]=0;
    }
    int m;
    scanf("%d",&m);
    int x,y,z;

    while(m--)
    {
        scanf("%d%d%d",&x,&y,&z);
        mapp[x][y]=mapp[y][x]=z;
    }
    dij();
    return 0;
}
/* IMU Zero Calibrates the MPU6050 to compensate for measurement deviations or errors that may occur due to factors such as gyroscope and accelerometer offset. When running this example, the code adjusts the MPU6050 sensor's acceleration (X,Y,Z) and rotation (gyroscope) axis offset values to ensure that the readings are as accurate as possible when the device is at rest. To get better results consider: 1. The MPU6050 module is working fine. 2. Put the MPU6050 on a flat and horizontal surface, and leave it operating for 5-10 minutes so its temperature gets stabilized. 4. Is in a location where the pull of gravity is 1g. During the execution it will generate a dozen outputs, showing that for each of the 6 desired offsets, it is: - First, try to find two estimates, one too low and one too high. - Closing in until the bracket can't be made smaller. The line just above the "done" (it will take a few minutes to get there) describes the optimum offsets for the X acceleration, Y acceleration, Z acceleration, X gyro, Y gyro, and Z gyro, respectively. Find the full MPU6050 library documentation here: https://github.com/ElectronicCats/mpu6050/wiki */ #include "I2Cdev.h" #include "MPU6050.h" /* Create the class for MPU6050. Default I2C address is 0x68 */ MPU6050 mpu; // MPU6050 mpu(0x69); // <-- use for AD0 high const int usDelay = 3150; // Delay in ms to hold the sampling at 200Hz const int NFast = 1000; // Number of quick readings for averaging, the higher the better const int NSlow = 10000; // Number of slow readings for averaging, the higher the better const int LinesBetweenHeaders = 5; const int iAx = 0; const int iAy = 1; const int iAz = 2; const int iGx = 3; const int iGy = 4; const int iGz = 5; int LowValue[6]; int HighValue[6]; int Smoothed[6]; int LowOffset[6]; int HighOffset[6]; int Target[6]; int LinesOut; int N; int i; void setup() { Initialize(); //Initializate and calibrate the sensor for (i = iAx; i <= iGz; i++) { Target[i] = 0; // Fix for ZAccel HighOffset[i] = 0; LowOffset[i] = 0; } Target[iAz] = 16384; // Set the taget for Z axes SetAveraging(NFast); // Fast averaging PullBracketsOut(); PullBracketsIn(); Serial.println("-------------- DONE --------------"); } void loop() { //Write your code here } /*Initializate function*/ void Initialize() { #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.begin(9600); // Init the module Serial.println("Initializing MPU..."); mpu.initialize(); Serial.println("MPU initializated"); // Check module connection Serial.println("Testing device connections..."); if(mpu.testConnection() == false){ Serial.println("MPU6050 connection failed"); while(true); } else{ Serial.println("MPU6050 connection successful"); } Serial.println("\nPID tuning Each Dot = 100 readings"); /* PID tuning (actually PI) works like this: changing the offset in the MPU6050 gives instant results, allowing us to use the Proportional and Integral parts of the PID to find the ideal offsets. The Integral uses the error from the set point (which is zero) and adds a fraction of this error to the integral value. Each reading reduces the error towards the desired offset. The greater the error, the more we adjust the integral value. The Proportional part helps by filtering out noise from the integral calculation. The Derivative part is not used due to noise and the sensor being stationary. With the noise removed, the integral value stabilizes after about 600 readings. At the end of each set of 100 readings, the integral value is used for the actual offsets, and the last proportional reading is ignored because it reacts to any noise. */ Serial.println("\nXAccel\t\tYAccel\t\tZAccel\t\tXGyro\t\tYGyro\t\tZGyro"); mpu.CalibrateAccel(6); mpu.CalibrateGyro(6); Serial.println("\n600 Readings"); mpu.PrintActiveOffsets(); mpu.CalibrateAccel(1); mpu.CalibrateGyro(1); Serial.println("700 Total Readings"); mpu.PrintActiveOffsets(); mpu.CalibrateAccel(1); mpu.CalibrateGyro(1); Serial.println("800 Total Readings"); mpu.PrintActiveOffsets(); mpu.CalibrateAccel(1); mpu.CalibrateGyro(1); Serial.println("900 Total Readings"); mpu.PrintActiveOffsets(); mpu.CalibrateAccel(1); mpu.CalibrateGyro(1); Serial.println("1000 Total Readings"); mpu.PrintActiveOffsets(); Serial.println("\nAny of the above offsets will work nicely \n\nProving the PID with other method:"); } void SetAveraging(int NewN) { N = NewN; Serial.print("\nAveraging "); Serial.print(N); Serial.println(" readings each time"); } void PullBracketsOut() { boolean Done = false; int NextLowOffset[6]; int NextHighOffset[6]; Serial.println("Expanding:"); ForceHeader(); while (!Done) { Done = true; SetOffsets(LowOffset); //Set low offsets GetSmoothed(); for (i = 0; i <= 5; i++) { // Get low values LowValue[i] = Smoothed[i]; if (LowValue[i] >= Target[i]) { Done = false; NextLowOffset[i] = LowOffset[i] - 1000; } else { NextLowOffset[i] = LowOffset[i]; } } SetOffsets(HighOffset); GetSmoothed(); for (i = 0; i <= 5; i++) { // Get high values HighValue[i] = Smoothed[i]; if (HighValue[i] <= Target[i]) { Done = false; NextHighOffset[i] = HighOffset[i] + 1000; } else { NextHighOffset[i] = HighOffset[i]; } } ShowProgress(); for (int i = 0; i <= 5; i++) { LowOffset[i] = NextLowOffset[i]; HighOffset[i] = NextHighOffset[i]; } } } void PullBracketsIn() { boolean AllBracketsNarrow; boolean StillWorking; int NewOffset[6]; Serial.println("\nClosing in:"); AllBracketsNarrow = false; ForceHeader(); StillWorking = true; while (StillWorking) { StillWorking = false; if (AllBracketsNarrow && (N == NFast)) { SetAveraging(NSlow); } else { AllBracketsNarrow = true; } for (int i = 0; i <= 5; i++) { if (HighOffset[i] <= (LowOffset[i] + 1)) { NewOffset[i] = LowOffset[i]; } else { // Binary search StillWorking = true; NewOffset[i] = (LowOffset[i] + HighOffset[i]) / 2; if (HighOffset[i] > (LowOffset[i] + 10)) { AllBracketsNarrow = false; } } } SetOffsets(NewOffset); GetSmoothed(); for (i = 0; i <= 5; i++) { // Closing in if (Smoothed[i] > Target[i]) { // Use lower half HighOffset[i] = NewOffset[i]; HighValue[i] = Smoothed[i]; } else { // Use upper half LowOffset[i] = NewOffset[i]; LowValue[i] = Smoothed[i]; } } ShowProgress(); } } void ForceHeader() { LinesOut = 99; } /*Function to smooth the read values*/ void GetSmoothed() { int16_t RawValue[6]; long Sums[6]; for (i = 0; i <= 5; i++) { Sums[i] = 0; } /* Get Sums*/ for (i = 1; i <= N; i++) { mpu.getMotion6( & RawValue[iAx], & RawValue[iAy], & RawValue[iAz], & RawValue[iGx], & RawValue[iGy], & RawValue[iGz]); delayMicroseconds(usDelay); for (int j = 0; j <= 5; j++){ Sums[j] = Sums[j] + RawValue[j]; } } for (i = 0; i <= 5; i++) { Smoothed[i] = (Sums[i] + N / 2) / N; } } /*Function for configure the oba=tained offsets*/ void SetOffsets(int TheOffsets[6]) { mpu.setXAccelOffset(TheOffsets[iAx]); mpu.setYAccelOffset(TheOffsets[iAy]); mpu.setZAccelOffset(TheOffsets[iAz]); mpu.setXGyroOffset(TheOffsets[iGx]); mpu.setYGyroOffset(TheOffsets[iGy]); mpu.setZGyroOffset(TheOffsets[iGz]); } /*Print the progress of the reading averages, add formatting for better visualization*/ void ShowProgress() { /*Header*/ if (LinesOut >= LinesBetweenHeaders) { Serial.println("\t\tXAccel\t\t\tYAccel\t\t\t\tZAccel\t\t\tXGyro\t\t\tYGyro\t\t\tZGyro"); LinesOut = 0; } Serial.print(' '); for (i = 0; i <= 5; i++) { Serial.print('['); Serial.print(LowOffset[i]), Serial.print(','); Serial.print(HighOffset[i]); Serial.print("] --> ["); Serial.print(LowValue[i]); Serial.print(','); Serial.print(HighValue[i]); if (i == 5) { Serial.println("]"); } else { Serial.print("]\t"); } } LinesOut++; } 此代码是干什么的?
最新发布
10-04
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

直接AC好吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值